Xamarin - Как получить скриншот и сохранить его на диск с помощью Xamarin Mac?
Я пытаюсь получить скриншот и сохранить его на диске, используя Xamarin и C# на Mac. Я написал код ниже:
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();
}
Метод выполняется, и файл появляется в правильном месте. Если я попытаюсь открыть его, он покажет пустым. Если я нажму "Получить информацию" в файле, он не будет отображать предварительный просмотр. После того, как я закрываю свое приложение, изображение может быть открыто, и "Get Info" показывает предварительный просмотр.
Что я здесь не так делаю? Мне кажется, что ресурсы не освобождаются, хотя я вызываю Dispose() для объектов.
Благодарю.
2 ответа
CGImageDestination.Create
Метод имеет 3 разных подписи, если вы используете ту, которая принимает NSUrl вместо CGDataConsumer
тебе должно быть хорошо.
var imageDestination = CGImageDestination.Create(fileURL, UTType.PNG, 1);
С этим вам не нужно создавать CGDataConsumer
но если вы действительно хотите / нужно
var dataConsumer = new CGDataConsumer(fileURL);
var imageDestination = CGImageDestination.Create(dataConsumer, UTType.PNG, 1);
imageDestination.AddImage(cgImage);
imageDestination.Close();
dataConsumer.Dispose();
Просто убедитесь, что утилизировали экземпляр, как только вы сохранили файл.
С using
подход:
using (var dataConsumer = new CGDataConsumer(fileURL))
{
var imageDestination = CGImageDestination.Create(dataConsumer, UTType.PNG, 1);
imageDestination.AddImage(cgImage);
imageDestination.Close();
}
Примечание: для CGImageDestination
вам не нужно утилизировать вручную, Close
Метод также выбрасывает объект (на основании документации).
public Boolean Close ()
Записывает изображения в пункт назначения и удаляет объект.
Надеюсь это поможет.-
Я могу опоздать, но только что реализовал этот алгоритм Swift с помощью Xamarin.Mac, и его можно использовать и в режиме без головы:
https://gist.github.com/MarcosCobena/b4768bacc1a112a4f38a9d11a19f1251
Он использует "новые" привязки CoreGraphics (некоторые уже присутствовали в Xamarin.Mac, но внутренние или частные) для обнаружения дисплеев и их перечисления. Наконец, он принимает один скриншот на экран, сохраняя его в формате PNG по заданному пути.