public override void DrawRect(CoreGraphics.CGRect dirtyRect) { base.DrawRect(dirtyRect); if (sample == null) { return; } // Just not that sharp using the scale pixel scale only // Going going 2x Pixel Scale var screenScale = (int)NSScreen.MainScreen.BackingScaleFactor * 2; var width = (int)Bounds.Width * screenScale; var height = (int)Bounds.Height * screenScale; IntPtr buff = System.Runtime.InteropServices.Marshal.AllocCoTaskMem(width * height * 4); try { using (var surface = SKSurface.Create(width, height, SKColorType.Rgba_8888, SKAlphaType.Premul, buff, width * 4)) { var skcanvas = surface.Canvas; skcanvas.Scale(screenScale, screenScale); Sample?.Method(skcanvas, (int)Bounds.Width, (int)Bounds.Height); } using (var colorSpace = CoreGraphics.CGColorSpace.CreateDeviceRGB()) { int hack = ((int)CoreGraphics.CGBitmapFlags.ByteOrderDefault) | ((int)CoreGraphics.CGImageAlphaInfo.PremultipliedLast); using (var bContext = new CoreGraphics.CGBitmapContext(buff, width, height, 8, width * 4, colorSpace, (CoreGraphics.CGImageAlphaInfo)hack)) { using (var image = bContext.ToImage()) { using (var context = NSGraphicsContext.CurrentContext.GraphicsPort) { context.DrawImage(Bounds, image); } } } } } finally { if (buff != IntPtr.Zero) { System.Runtime.InteropServices.Marshal.FreeCoTaskMem(buff); } } }
public override void DrawRect(CoreGraphics.CGRect dirtyRect) { base.DrawRect (dirtyRect); if (onDrawCallback == null) return; // Just not that sharp using the scale pixel scale only // Going going 2x Pixel Scale var screenScale = (int)NSScreen.MainScreen.BackingScaleFactor * 2; var width = (int)Bounds.Width * screenScale; var height = (int)Bounds.Height * screenScale; IntPtr buff = System.Runtime.InteropServices.Marshal.AllocCoTaskMem (width * height * 4); try { using (var surface = SKSurface.Create (width, height, SKColorType.Rgba_8888, SKAlphaType.Premul, buff, width * 4)) { var skcanvas = surface.Canvas; skcanvas.Scale (screenScale, screenScale); onDrawCallback (skcanvas, (int)Bounds.Width, (int)Bounds.Height); } using (var colorSpace = CoreGraphics.CGColorSpace.CreateDeviceRGB ()) { int hack = ((int)CoreGraphics.CGBitmapFlags.ByteOrderDefault) | ((int)CoreGraphics.CGImageAlphaInfo.PremultipliedLast); using (var bContext = new CoreGraphics.CGBitmapContext (buff, width, height, 8, width * 4, colorSpace, (CoreGraphics.CGImageAlphaInfo) hack)) { using (var image = bContext.ToImage ()) { using (var context = NSGraphicsContext.CurrentContext.GraphicsPort) { context.DrawImage (Bounds, image); } } } } } finally { if (buff != IntPtr.Zero) System.Runtime.InteropServices.Marshal.FreeCoTaskMem (buff); } }
async Task<UIImage> GenerateDocumentThumbnailAsync (IDocument s, Praeclarum.Graphics.SizeF size, Theme theme) { var scale = UIScreen.MainScreen.Scale; return await Task.Run (() => { var width = (int)(size.Width * scale); var height = (int)(size.Height * scale); using (var colorSpace = CoreGraphics.CGColorSpace.CreateDeviceRGB ()) { using (var c = new CoreGraphics.CGBitmapContext ( IntPtr.Zero, width, height, 8, 4 * width, colorSpace, CoreGraphics.CGImageAlphaInfo.NoneSkipFirst)) { c.TranslateCTM (0, height); c.ScaleCTM (scale, -scale); var g = new Praeclarum.Graphics.CoreGraphicsGraphics (c, true); App.DrawThumbnail (s, g, size, theme); // // Create the bitmap // return UIImage.FromImage (c.ToImage (), scale, UIImageOrientation.Up); } } }); }
internal static ImageStream GetImage(PHAsset asset, MediaFileGetImageOptions options) { nfloat w = options.Width; nfloat h = options.Height; switch (options.Orientation) { case MediaFileImageOrientation.Left: case MediaFileImageOrientation.LeftMirrored: case MediaFileImageOrientation.Right: case MediaFileImageOrientation.RightMirrored: var wT = w; w = h; h = wT; break; } if (w <= 0) { if (h > 0) { w = asset.PixelWidth * h / asset.PixelHeight; } else { w = asset.PixelWidth; } } if (h <= 0) { h = asset.PixelHeight * w / asset.PixelWidth; } ImageStream image = null; PHImageManager.DefaultManager.RequestImageForAsset( asset, new CoreGraphics.CGSize(w, h), ImageResizeAspectToPH(options.ResizeAspect), new PHImageRequestOptions { Synchronous = true, ResizeMode = PHImageRequestOptionsResizeMode.Exact }, (requestedImage, info) => { if (options.Orientation != MediaFileImageOrientation.Up || requestedImage.Size.Width != w || requestedImage.Size.Height != h) { var destW = w; var destH = h; if (options.ResizeAspect == MediaFileGetImageOptions.ImageResizeAspect.AspectFit) { var widthScale = w / requestedImage.Size.Width; var heightScale = h / requestedImage.Size.Height; var scale = (nfloat)Math.Min(widthScale, heightScale); switch (options.Orientation) { case MediaFileImageOrientation.Left: case MediaFileImageOrientation.LeftMirrored: case MediaFileImageOrientation.Right: case MediaFileImageOrientation.RightMirrored: h = requestedImage.Size.Width * scale; w = requestedImage.Size.Height * scale; destW = h; destH = w; break; default: w = requestedImage.Size.Width * scale; h = requestedImage.Size.Height * scale; destW = w; destH = h; break; } } else { switch (options.Orientation) { case MediaFileImageOrientation.Left: case MediaFileImageOrientation.LeftMirrored: case MediaFileImageOrientation.Right: case MediaFileImageOrientation.RightMirrored: var wT = w; w = h; h = wT; break; } } var cg = requestedImage.CGImage; int bytesPerRow = (int)w * 4; var ctx = new CoreGraphics.CGBitmapContext(null, (int)w, (int)h, 8, bytesPerRow, cg.ColorSpace, CoreGraphics.CGImageAlphaInfo.PremultipliedLast); Func <float, float> radians = (degrees) => { return(degrees * ((float)Math.PI / 180f)); }; switch (options.Orientation) { case MediaFileImageOrientation.UpMirrored: ctx.TranslateCTM(w, 0); ctx.ScaleCTM(-1f, 1f); break; case MediaFileImageOrientation.Down: ctx.TranslateCTM(w, h); ctx.RotateCTM(radians(180f)); break; case MediaFileImageOrientation.DownMirrored: ctx.TranslateCTM(0, h); ctx.RotateCTM(radians(180f)); ctx.ScaleCTM(-1f, 1f); break; case MediaFileImageOrientation.Left: ctx.TranslateCTM(w, 0); ctx.RotateCTM(radians(90f)); break; case MediaFileImageOrientation.LeftMirrored: ctx.TranslateCTM(w, h); ctx.RotateCTM(radians(270f)); ctx.ScaleCTM(1f, -1f); break; case MediaFileImageOrientation.Right: ctx.TranslateCTM(0, h); ctx.RotateCTM(radians(270f)); break; case MediaFileImageOrientation.RightMirrored: ctx.TranslateCTM(0, 0); ctx.RotateCTM(radians(90f)); ctx.ScaleCTM(1f, -1f); break; default: break; } ctx.DrawImage(new CoreGraphics.CGRect(0, 0, destW, destH), cg); requestedImage = UIImage.FromImage(ctx.ToImage()); ctx.Dispose(); } using (var stream = requestedImage.AsJPEG(options.Quality / 100f).AsStream()) { image = ImageStream.FromStream(stream, (int)requestedImage.Size.Width, (int)requestedImage.Size.Height); } requestedImage.Dispose(); }); return(image); }
public static unsafe UIKit.UIImage GetUIImage(MPSImage mpsImage) { var width = (int)mpsImage.Width; var height = (int)mpsImage.Height; var nfc = (int)mpsImage.FeatureChannels; var obytesPerRow = 4 * width; var cellSize = 44; using var cs = CoreGraphics.CGColorSpace.CreateDeviceRGB(); //Console.WriteLine ((width, height, mpsImage.Precision, mpsImage.PixelSize, mpsImage.FeatureChannels, mpsImage.PixelFormat, mpsImage.FeatureChannelFormat)); if (mpsImage.FeatureChannelFormat == MPSImageFeatureChannelFormat.Float32 && nfc == 3) { var data = new float[width * height * nfc]; fixed(float *dataPointer = data) { mpsImage.ReadBytes((IntPtr)dataPointer, MPSDataLayout.HeightPerWidthPerFeatureChannels, 0); } using var bc = new CoreGraphics.CGBitmapContext(null, width, height, 8, obytesPerRow, cs, CoreGraphics.CGImageAlphaInfo.NoneSkipFirst); var pixels = (byte *)bc.Data; var p = pixels; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { *p++ = 255; *p++ = ClampRGBA32Float(data[y * (width * 3) + x * 3 + 2]); *p++ = ClampRGBA32Float(data[y * (width * 3) + x * 3 + 1]); *p++ = ClampRGBA32Float(data[y * (width * 3) + x * 3 + 0]); } } var cgimage = bc.ToImage(); //Console.WriteLine ($"pixels f32 = " + string.Join (", ", data.Skip (data.Length / 2).Take (12))); return(UIImage.FromImage(cgimage)); } else if (mpsImage.FeatureChannelFormat == MPSImageFeatureChannelFormat.Float32 && nfc == 1) { var data = new float[width * height * nfc]; fixed(float *dataPointer = data) { mpsImage.ReadBytes((IntPtr)dataPointer, MPSDataLayout.HeightPerWidthPerFeatureChannels, 0); } using var bc = new CoreGraphics.CGBitmapContext(null, width, height, 8, obytesPerRow, cs, CoreGraphics.CGImageAlphaInfo.NoneSkipFirst); var pixels = (byte *)bc.Data; var p = pixels; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var g = ClampRGBA32Float(data[y * width + x]); * p++ = 255; * p++ = g; * p++ = g; * p++ = g; } } var cgimage = bc.ToImage(); //Console.WriteLine ($"pixels f32 = " + string.Join (", ", data.Skip (data.Length / 2).Take (12))); return(UIImage.FromImage(cgimage)); } else if (mpsImage.FeatureChannelFormat == MPSImageFeatureChannelFormat.Unorm8 && nfc == 3) { var data = new byte[width * height * (int)mpsImage.FeatureChannels]; fixed(byte *dataPointer = data) { mpsImage.ReadBytes((IntPtr)dataPointer, MPSDataLayout.HeightPerWidthPerFeatureChannels, 0); //mpsImage.Texture.GetBytes ((IntPtr)dataPointer, (nuint)(4 * width), MTLRegion.Create3D (0, 0, 0, width, height, 1), 0); } using var bc = new CoreGraphics.CGBitmapContext(null, width, height, 8, obytesPerRow, cs, CoreGraphics.CGImageAlphaInfo.NoneSkipFirst); var pixels = (byte *)bc.Data; var p = pixels; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { *p++ = 255; *p++ = data[y * (width * 3) + x * 3 + 2]; // Red *p++ = data[y * (width * 3) + x * 3 + 1]; // Green *p++ = data[y * (width * 3) + x * 3 + 0]; // Blue } } var cgimage = bc.ToImage(); //Console.WriteLine ($"pixels 3 unorm8 = " + string.Join (", ", data.Skip (data.Length / 2).Take (12))); return(UIImage.FromImage(cgimage)); } else if (mpsImage.FeatureChannelFormat == MPSImageFeatureChannelFormat.Unorm8 && nfc == 1) { var data = new byte[width * height * (int)mpsImage.FeatureChannels]; fixed(byte *dataPointer = data) { mpsImage.ReadBytes((IntPtr)dataPointer, MPSDataLayout.HeightPerWidthPerFeatureChannels, 0); //mpsImage.Texture.GetBytes ((IntPtr)dataPointer, (nuint)(4 * width), MTLRegion.Create3D (0, 0, 0, width, height, 1), 0); } using var bc = new CoreGraphics.CGBitmapContext(null, width, height, 8, obytesPerRow, cs, CoreGraphics.CGImageAlphaInfo.NoneSkipFirst); var pixels = (byte *)bc.Data; var p = pixels; for (var y = 0; y < height; y++) { for (var x = 0; x < width; x++) { var g = data[y * width + x]; // Red * p++ = 255; * p++ = g; * p++ = g; * p++ = g; } } var cgimage = bc.ToImage(); //Console.WriteLine ($"pixels 1 unorm8 = " + string.Join (", ", data.Skip (data.Length / 2).Take (12))); return(UIImage.FromImage(cgimage)); } else if (mpsImage.FeatureChannelFormat == MPSImageFeatureChannelFormat.Float32 && width == 1 && height == 1) { var data = new float[width * height * nfc]; fixed(void *dataPointer = data) { mpsImage.ReadBytes((IntPtr)dataPointer, MPSDataLayout.HeightPerWidthPerFeatureChannels, 0); } return(DrawCells(nfc, cellSize, data)); } else if (mpsImage.FeatureChannelFormat == MPSImageFeatureChannelFormat.Unorm8 && width == 1 && height == 1) { var data = new byte[width * height * nfc]; fixed(void *dataPointer = data) { mpsImage.ReadBytes((IntPtr)dataPointer, MPSDataLayout.HeightPerWidthPerFeatureChannels, 0); } return(DrawCells(nfc, cellSize, data.Select(x => x / 255.0f).ToArray())); } else { if (width == 1 && height == 1) { width = cellSize; height = cellSize; } UIGraphics.BeginImageContext(new CoreGraphics.CGSize(width, height)); UIColor.Red.SetColor(); var m = $"{mpsImage.FeatureChannels}{mpsImage.FeatureChannelFormat}?"; m.DrawString(new CoreGraphics.CGPoint(0, 0), UIFont.SystemFontOfSize(8)); var image = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); return(image); } }