I'm trying to grab a screenshot and save it on disk using Xamarin and C# on Mac. I wrote the code below:
public static void TakeScreenshotAndSaveToDisk(string path)
{
var fullScreenBounds = NSScreen.MainScreen.Frame;
IntPtr ptr = CGWindowListCreateImage(fullScreenBounds, CGWindowListOption.OnScreenAboveWindow, 0, CGWindowImageOption.Default);
var cgImage = new CGImage(ptr);
var fileURL = new NSUrl(path, false);
var imageDestination = CGImageDestination.Create(new CGDataConsumer(fileURL), UTType.PNG, 1);
imageDestination.AddImage(cgImage);
imageDestination.Close();
imageDestination.Dispose();
fileURL.Dispose();
cgImage.Dispose();
}
The method executes and the file appears at the correct location. If I try to open it, it will show blank. If I click "Get Info" on the file it will not show a preview. After I close my app, the image can be opened and "Get Info" shows the preview.
What am I doing wrong here? It seems to me that the resources are not released even though I call Dispose() on the objects.
Thanks.
The CGImageDestination.Create
method has 3 different signatures, if you use the one that accepts a NSUrl instead of a CGDataConsumer
you should be good.
var imageDestination = CGImageDestination.Create(fileURL, UTType.PNG, 1);
With this one you don't need to create a CGDataConsumer
but if you really want/need to
var dataConsumer = new CGDataConsumer(fileURL);
var imageDestination = CGImageDestination.Create(dataConsumer, UTType.PNG, 1);
imageDestination.AddImage(cgImage);
imageDestination.Close();
dataConsumer.Dispose();
Just make sure to dispose the instance once you have saved the file.
With the using
approach:
using (var dataConsumer = new CGDataConsumer(fileURL))
{
var imageDestination = CGImageDestination.Create(dataConsumer, UTType.PNG, 1);
imageDestination.AddImage(cgImage);
imageDestination.Close();
}
Note: for the CGImageDestination
you don't need to manually dispose, the Close
method will also dispose the object (based on the documentation).
public Boolean Close ()
Writes the images to the destination and disposes the object.
Hope this helps.-