using CPF.Mac.Foundation; using CPF.Mac.ObjCRuntime; using System; using System.Runtime.InteropServices; namespace CPF.Mac.CoreGraphics { public class CGImage : INativeObject, IDisposable { internal IntPtr handle; public IntPtr Handle => handle; public bool IsMask => CGImageIsMask(handle) != 0; public int Width => CGImageGetWidth(handle).ToInt32(); public int Height => CGImageGetHeight(handle).ToInt32(); public int BitsPerComponent => CGImageGetBitsPerComponent(handle).ToInt32(); public int BitsPerPixel => CGImageGetBitsPerPixel(handle).ToInt32(); public int BytesPerRow => CGImageGetBytesPerRow(handle).ToInt32(); public CGColorSpace ColorSpace => new CGColorSpace(CGImageGetColorSpace(handle)); public CGImageAlphaInfo AlphaInfo => CGImageGetAlphaInfo(handle); public CGDataProvider DataProvider => new CGDataProvider(CGImageGetDataProvider(handle)); public unsafe double* Decode => CGImageGetDecode(handle); public bool ShouldInterpolate => CGImageGetShouldInterpolate(handle) != 0; public CGColorRenderingIntent RenderingIntent => CGImageGetRenderingIntent(handle); public CGBitmapFlags BitmapInfo => CGImageGetBitmapInfo(handle); public CGImage(IntPtr handle) : this(handle, owns: false) { this.handle = handle; } [Preserve(Conditional = true)] internal CGImage(IntPtr handle, bool owns) { this.handle = handle; if (!owns) { CGImageRetain(handle); } } ~CGImage() { Dispose(disposing: false); } public void Dispose() { Dispose(disposing: true); GC.SuppressFinalize(this); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern void CGImageRelease(IntPtr handle); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern void CGImageRetain(IntPtr handle); protected virtual void Dispose(bool disposing) { if (handle != IntPtr.Zero) { CGImageRelease(handle); handle = IntPtr.Zero; } } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreate(IntPtr size_t_width, IntPtr size_t_height, IntPtr size_t_bitsPerComponent, IntPtr size_t_bitsPerPixel, IntPtr size_t_bytesPerRow, IntPtr space, CGBitmapFlags bitmapInfo, IntPtr provider, double[] decode, bool shouldInterpolate, CGColorRenderingIntent intent); public CGImage(long width, long height, long bitsPerComponent, long bitsPerPixel, long bytesPerRow, CGColorSpace colorSpace, CGBitmapFlags bitmapFlags, CGDataProvider provider, double[] decode, bool shouldInterpolate, CGColorRenderingIntent intent) { if (colorSpace == null) { throw new ArgumentNullException("colorSpace"); } if (width < 0) { throw new ArgumentException("width"); } if (height < 0) { throw new ArgumentException("height"); } if (bitsPerPixel < 0) { throw new ArgumentException("bitsPerPixel"); } if (bitsPerComponent < 0) { throw new ArgumentException("bitsPerComponent"); } if (bytesPerRow < 0) { throw new ArgumentException("bytesPerRow"); } handle = CGImageCreate(new IntPtr(width), new IntPtr(height), new IntPtr(bitsPerComponent), new IntPtr(bitsPerPixel), new IntPtr(bytesPerRow), colorSpace.Handle, bitmapFlags, provider?.Handle ?? IntPtr.Zero, decode, shouldInterpolate, intent); } public CGImage(long width, long height, long bitsPerComponent, long bitsPerPixel, long bytesPerRow, CGColorSpace colorSpace, CGImageAlphaInfo alphaInfo, CGDataProvider provider, double[] decode, bool shouldInterpolate, CGColorRenderingIntent intent) { if (colorSpace == null) { throw new ArgumentNullException("colorSpace"); } if (width < 0) { throw new ArgumentException("width"); } if (height < 0) { throw new ArgumentException("height"); } if (bitsPerPixel < 0) { throw new ArgumentException("bitsPerPixel"); } if (bitsPerComponent < 0) { throw new ArgumentException("bitsPerComponent"); } if (bytesPerRow < 0) { throw new ArgumentException("bytesPerRow"); } handle = CGImageCreate(new IntPtr(width), new IntPtr(height), new IntPtr(bitsPerComponent), new IntPtr(bitsPerPixel), new IntPtr(bytesPerRow), colorSpace.Handle, (CGBitmapFlags)alphaInfo, provider?.Handle ?? IntPtr.Zero, decode, shouldInterpolate, intent); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] public static extern IntPtr CGWindowListCreateImage(CGRect screenBounds, CGWindowListOption windowOption, uint windowID, CGWindowImageOption imageOption); public static CGImage ScreenImage(int windownumber, CGRect bounds) { return new CGImage(CGWindowListCreateImage(bounds, CGWindowListOption.IncludingWindow, (uint)windownumber, CGWindowImageOption.Default), owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreateWithJPEGDataProvider(IntPtr source, double[] decode, bool shouldInterpolate, CGColorRenderingIntent intent); public static CGImage FromJPEG(CGDataProvider provider, double[] decode, bool shouldInterpolate, CGColorRenderingIntent intent) { if (provider == null) { throw new ArgumentNullException("provider"); } IntPtr value = CGImageCreateWithJPEGDataProvider(provider.Handle, decode, shouldInterpolate, intent); if (value == IntPtr.Zero) { return null; } return new CGImage(value, owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreateWithPNGDataProvider(IntPtr source, double[] decode, bool shouldInterpolate, CGColorRenderingIntent intent); public static CGImage FromPNG(CGDataProvider provider, double[] decode, bool shouldInterpolate, CGColorRenderingIntent intent) { if (provider == null) { throw new ArgumentNullException("provider"); } IntPtr value = CGImageCreateWithPNGDataProvider(provider.Handle, decode, shouldInterpolate, intent); if (value == IntPtr.Zero) { return null; } return new CGImage(value, owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageMaskCreate(IntPtr size_t_width, IntPtr size_t_height, IntPtr size_t_bitsPerComponent, IntPtr size_t_bitsPerPixel, IntPtr size_t_bytesPerRow, IntPtr provider, double[] decode, bool shouldInterpolate); public static CGImage CreateMask(long width, long height, long bitsPerComponent, long bitsPerPixel, long bytesPerRow, CGDataProvider provider, double[] decode, bool shouldInterpolate) { if (width < 0) { throw new ArgumentException("width"); } if (height < 0) { throw new ArgumentException("height"); } if (bitsPerPixel < 0) { throw new ArgumentException("bitsPerPixel"); } if (bytesPerRow < 0) { throw new ArgumentException("bytesPerRow"); } if (provider == null) { throw new ArgumentNullException("provider"); } IntPtr value = CGImageMaskCreate(new IntPtr(width), new IntPtr(height), new IntPtr(bitsPerComponent), new IntPtr(bitsPerPixel), new IntPtr(bytesPerRow), provider.Handle, decode, shouldInterpolate); if (value == IntPtr.Zero) { return null; } return new CGImage(value, owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreateWithMaskingColors(IntPtr image, double[] components); public CGImage WithMaskingColors(double[] components) { int num = 2 * ColorSpace.Components; if (components == null) { throw new ArgumentNullException("components"); } if (components.Length != num) { throw new ArgumentException("The argument 'components' must have 2N values, where N is the number of components in the color space of the image.", "components"); } return new CGImage(CGImageCreateWithMaskingColors(Handle, components), owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreateCopy(IntPtr image); public CGImage Clone() { return new CGImage(CGImageCreateCopy(handle), owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreateCopyWithColorSpace(IntPtr image, IntPtr space); public CGImage WithColorSpace(CGColorSpace cs) { return new CGImage(CGImageCreateCopyWithColorSpace(handle, cs.handle), owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreateWithImageInRect(IntPtr image, CGRect rect); public CGImage WithImageInRect(CGRect rect) { return new CGImage(CGImageCreateWithImageInRect(handle, rect), owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageCreateWithMask(IntPtr image, IntPtr mask); public CGImage WithMask(CGImage mask) { return new CGImage(CGImageCreateWithMask(handle, mask.handle), owns: true); } [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern int CGImageIsMask(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageGetWidth(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageGetHeight(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageGetBitsPerComponent(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageGetBitsPerPixel(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageGetBytesPerRow(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageGetColorSpace(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern CGImageAlphaInfo CGImageGetAlphaInfo(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern IntPtr CGImageGetDataProvider(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private unsafe static extern double* CGImageGetDecode(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern int CGImageGetShouldInterpolate(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern CGColorRenderingIntent CGImageGetRenderingIntent(IntPtr image); [DllImport("/System/Library/Frameworks/ApplicationServices.framework/Versions/A/Frameworks/CoreGraphics.framework/CoreGraphics")] private static extern CGBitmapFlags CGImageGetBitmapInfo(IntPtr image); } }