Skip to content

Instantly share code, notes, and snippets.

@Mrnikbobjeff
Last active October 9, 2020 09:36
Show Gist options
  • Save Mrnikbobjeff/7fb533642a1b9bfeb7376a79d43da7dc to your computer and use it in GitHub Desktop.
Save Mrnikbobjeff/7fb533642a1b9bfeb7376a79d43da7dc to your computer and use it in GitHub Desktop.
using System.Buffers;
using System.IO;
using System.Threading.Tasks;
using AppKit;
using CoreGraphics;
using CoreImage;
using Foundation;
using ImageIO;
using MobileCoreServices;
namespace Xamarin.Essentials
{
public static partial class Screenshot
{
internal static bool PlatformIsCaptureSupported => true;
static Task<ScreenshotResult> PlatformCaptureAsync()
{
var window = Platform.GetCurrentWindow(true);
using var image = CGImage.ScreenImage((int)window.WindowNumber, window.ContentLayoutRect);
var result = new ScreenshotResult(new NSImage(image, new CGSize(image.Width, image.Height)));
return Task.FromResult(result);
}
}
public partial class ScreenshotResult
{
internal class ImageTypeStream : Stream
{
readonly Stream decoratedStream;
readonly CGImage nativeImage;
internal ImageTypeStream(CGImage image, ScreenshotFormat format)
{
var utType = format switch
{
ScreenshotFormat.Jpeg => UTType.JPEG,
_ => UTType.PNG
};
var data = new NSMutableData();
var dest = CGImageDestination.Create(data, utType, imageCount: 1);
dest.AddImage(image);
dest.Close();
decoratedStream = data.AsStream();
}
public override bool CanRead => decoratedStream.CanRead;
public override bool CanSeek => decoratedStream.CanSeek;
public override bool CanWrite => decoratedStream.CanWrite;
public override long Length => decoratedStream.Length;
public override long Position { get => decoratedStream.Position; set => decoratedStream.Position = value; }
public override void Flush() => decoratedStream.Flush();
public override int Read(byte[] buffer, int offset, int count) => decoratedStream.Read(buffer, offset, count);
public override long Seek(long offset, SeekOrigin origin) => decoratedStream.Seek(offset, origin);
public override void SetLength(long value) => decoratedStream.SetLength(value);
public override void Write(byte[] buffer, int offset, int count) => decoratedStream.Write(buffer, offset, count);
protected override void Dispose(bool disposing)
{
nativeImage.Dispose();
base.Dispose(disposing);
}
}
readonly NSImage uiImage;
internal ScreenshotResult(NSImage image)
{
uiImage = image;
Width = (int)image.Size.Width;
Height = (int)image.Size.Height;
}
internal Task<Stream> PlatformOpenReadAsync(ScreenshotFormat format)
{
return Task.FromResult<Stream>(new ImageTypeStream(uiImage.CGImage, format));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment