public static NSImage CropImagesFromSizeToSize(NSImage sourceImage, CGSize sourceSize, CGSize destSize) { var originalWidth = sourceImage.Size.Width; var originalHeight = sourceImage.Size.Height; var corpWidth = (sourceSize.Height / destSize.Height) * destSize.Width; var numberOfFrame = originalWidth / sourceSize.Width; var thumbnial_all_image = new NSImage(new CGSize(destSize.Width * numberOfFrame, destSize.Height)); thumbnial_all_image.LockFocus(); var newImageRect = new CGRect(0, 0, 0, 0); newImageRect.Size = thumbnial_all_image.Size; for (var i = 0; i < numberOfFrame; i++) { sourceImage.DrawInRect( new CGRect((destSize.Width * i), 0, destSize.Width, destSize.Height), new CGRect((sourceSize.Width * i) + (sourceSize.Width / 2) - (corpWidth / 2), 0, corpWidth, sourceSize.Height), NSCompositingOperation.SourceOver, 1); } thumbnial_all_image.UnlockFocus(); return(thumbnial_all_image); }
public static NSImage Resize(this NSImage image, CGSize destSize, NSImageScalingMode scalingMode, NSImageSizing sizingMode) { var sourceSize = image.Size; var wantToScaleUp = (destSize.Height > sourceSize.Height || destSize.Width > sourceSize.Width); var canScaleUp = (NSImageSizing.Up & sizingMode) == NSImageSizing.Up; var wantToScaleDown = (destSize.Height < sourceSize.Height || destSize.Width < sourceSize.Width); var canScaleDown = (NSImageSizing.Down & sizingMode) == NSImageSizing.Down; if (!canScaleDown && wantToScaleDown) { sourceSize.Width = destSize.Width; sourceSize.Height = destSize.Height; } if (!canScaleUp && wantToScaleUp) { destSize.Width = sourceSize.Width; destSize.Height = sourceSize.Height; } var destRect = new CGRect(0, 0, destSize.Width, destSize.Height); var sourceRect = new CGRect(0, 0, sourceSize.Width, sourceSize.Height); var targetImage = new NSImage(destSize); if (scalingMode != NSImageScalingMode.ScaleToFill) { float ratioH = (float)(destSize.Height / sourceSize.Height); float ratioW = (float)(destSize.Width / sourceSize.Width); var fill = scalingMode == NSImageScalingMode.ScaleAspectFill; var h = ratioH >= ratioW; if ((fill && !h) || (h && !fill)) { var newSize = new CGSize(sourceSize.Width, destSize.Height / ratioW); sourceRect = new CGRect(sourceRect.Location, newSize); } else { var newSize = new CGSize(Math.Floor(destSize.Width / ratioH), sourceSize.Height); sourceRect = new CGRect(sourceRect.Location, newSize); } } var newX = Math.Floor((sourceSize.Width - sourceRect.Size.Width) / 2); var newY = Math.Floor((sourceSize.Height - sourceRect.Size.Height) / 2); sourceRect.Location = new CGPoint(newX, newY); targetImage.LockFocus(); image.DrawInRect(destRect, sourceRect, NSCompositingOperation.Copy, 1.0f); targetImage.UnlockFocus(); return(targetImage); }
internal static NSImage ResizeImage(NSImage image, CGSize size) { var resized = new NSImage(size); resized.LockFocus(); NSGraphicsContext.CurrentContext.ImageInterpolation = NSImageInterpolation.High; image.DrawInRect(new CGRect(0, 0, size.Width, size.Height), new CGRect(CGPoint.Empty, image.Size), NSCompositingOperation.Copy, 1.0f); resized.UnlockFocus(); return(resized); }
public override void DrawImage(NSImage image, CGRect frame, NSView controlView) { NSGraphicsContext.GlobalSaveGraphicsState (); { this.shadow.Set (); CGRect imgRect = frame.Inset ((frame.Size.Width - image.Size.Width) / 2.0f, (frame.Size.Height - image.Size.Height) / 2.0f); image.Flipped = true; image.DrawInRect (imgRect, CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); } NSGraphicsContext.GlobalRestoreGraphicsState (); }
private NSImage Resize(NSImage image, double width, double height) { var newImage = new NSImage(new CGSize(width, height)); newImage.LockFocus(); image.DrawInRect(new CGRect(0, 0, width, height), new CGRect(0, 0, image.Size.Width, image.Size.Height), NSCompositingOperation.SourceOver, 1); newImage.UnlockFocus(); return(newImage); }
//- (NSImage *)thumbImageFromImage:(NSImage *)image; async Task <NSImage> ThumbImageFromImageAsync(NSImage image) { nfloat targetHeight = 200.0f; CGSize imageSize = image.Size; CGSize smallerSize = new CGSize(targetHeight * imageSize.Width / imageSize.Height, targetHeight); NSImage smallerImage = new NSImage(smallerSize); smallerImage.LockFocus(); image.DrawInRect(new CGRect(0, 0, smallerSize.Width, smallerSize.Height), CGRect.Empty, NSCompositingOperation.Copy, 1.0f); smallerImage.UnlockFocus(); return(smallerImage); }
public static NSImage Resize(this NSImage image, CGSize newsize, ImageInterpolation interpolation = ImageInterpolation.Default) { var newimage = new NSImage(newsize); var newrep = new NSBitmapImageRep(IntPtr.Zero, (nint)newsize.Width, (nint)newsize.Height, 8, 4, true, false, NSColorSpace.DeviceRGB, 4 * (nint)newsize.Width, 32); newimage.AddRepresentation(newrep); var graphics = NSGraphicsContext.FromBitmap(newrep); NSGraphicsContext.GlobalSaveGraphicsState(); NSGraphicsContext.CurrentContext = graphics; graphics.GraphicsPort.InterpolationQuality = interpolation.ToCG(); image.DrawInRect(new CGRect(CGPoint.Empty, newimage.Size), new CGRect(CGPoint.Empty, image.Size), NSCompositingOperation.SourceOver, 1f); NSGraphicsContext.GlobalRestoreGraphicsState(); return(newimage); }
private NSImage ResizeImage(NSImage sourceImage, double resizeFactor) { var sourceSize = sourceImage.Size; float width = (float)(resizeFactor * sourceSize.Width); float height = (float)(resizeFactor * sourceSize.Height); var targetRect = new CoreGraphics.CGRect(0, 0, width, height); var newImage = new NSImage(new CoreGraphics.CGSize(width, height)); newImage.LockFocus(); sourceImage.DrawInRect(targetRect, CoreGraphics.CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); newImage.UnlockFocus(); ConstraintImageViewWidth.Constant = width; ConstraintImageViewHeight.Constant = height; return(newImage); }
public static NSImage ResizeImageToSize(NSImage sourceImage, CGSize destSize) { //Console.WriteLine("Original Size is {0}", sourceImage.Size); float renderWidth = (float)sourceImage.Size.Width; float renderHeight = (float)sourceImage.Size.Height; float cropWidth = (float)destSize.Width; float cropHeight = (float)destSize.Height; // Resize Width var radio = renderWidth / cropWidth; cropHeight = cropHeight * radio; cropWidth = renderWidth; // Resize Height if (cropHeight > renderHeight) { radio = renderHeight / cropHeight; cropWidth = cropWidth * radio; cropHeight = renderHeight; } //Console.WriteLine("Crop Size is {0}, {1}", cropWidth, cropHeight); var cropX = (renderWidth - cropWidth) / 2; var cropY = (renderHeight - cropHeight) / 2; var renderImage = new NSImage(destSize); renderImage.LockFocus(); sourceImage.DrawInRect( new CGRect(0, 0, destSize.Width, destSize.Height), new CGRect(cropX, cropY, cropWidth, cropHeight), NSCompositingOperation.SourceOver, 1); renderImage.UnlockFocus(); return(renderImage); }
/// <summary> /// Combines two images into a new one, so that the "badge" image overlays the bottom-right quarter of the other image. /// </summary> /// <returns>The with badge.</returns> /// <param name="icon">Background of the new image</param> /// <param name="badge">Overlay image</param> internal static NSImage IconWithBadge(NSImage icon, NSImage badge) { if (icon == null) { return(null); } if (badge == null) { return(icon); } var result = (NSImage)icon.Copy(); result.LockFocus(); NSGraphicsContext.CurrentContext.ImageInterpolation = NSImageInterpolation.High; var dstRect = new CGRect(icon.Size.Width / 2, 0, icon.Size.Width / 2, icon.Size.Height / 2); var srcRect = new CGRect(0, 0, badge.Size.Width, badge.Size.Height); badge.DrawInRect(dstRect, srcRect, NSCompositingOperation.SourceOver, 1.0f); result.UnlockFocus(); return(result); }
public static void ReadImageFileToTensor <T>( String fileName, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, bool flipUpSideDown = false, bool swapBR = false) where T : struct { #if __ANDROID__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } if (swapBR) { throw new NotImplementedException("swapBR is Not implemented"); } Android.Graphics.Bitmap bmp = BitmapFactory.DecodeFile(fileName); if (inputHeight > 0 || inputWidth > 0) { Bitmap resized = Bitmap.CreateScaledBitmap(bmp, inputWidth, inputHeight, false); bmp.Dispose(); bmp = resized; } int[] intValues = new int[bmp.Width * bmp.Height]; float[] floatValues = new float[bmp.Width * bmp.Height * 3]; bmp.GetPixels(intValues, 0, bmp.Width, 0, 0, bmp.Width, bmp.Height); for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __IOS__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } if (swapBR) { throw new NotImplementedException("swapBR is Not implemented"); } UIImage image = new UIImage(fileName); if (inputHeight > 0 || inputWidth > 0) { UIImage resized = image.Scale(new CGSize(inputWidth, inputHeight)); image.Dispose(); image = resized; } int[] intValues = new int[(int)(image.Size.Width * image.Size.Height)]; float[] floatValues = new float[(int)(image.Size.Width * image.Size.Height * 3)]; System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned); using (CGImage cgimage = image.CGImage) using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB()) using (CGBitmapContext context = new CGBitmapContext( handle.AddrOfPinnedObject(), (nint)image.Size.Width, (nint)image.Size.Height, 8, (nint)image.Size.Width * 4, cspace, CGImageAlphaInfo.PremultipliedLast )) { context.DrawImage(new CGRect(new CGPoint(), image.Size), cgimage); } handle.Free(); for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __UNIFIED__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } if (swapBR) { throw new NotImplementedException("swapBR is Not implemented"); } NSImage image = new NSImage(fileName); if (inputHeight > 0 || inputWidth > 0) { NSImage resized = new NSImage(new CGSize(inputWidth, inputHeight)); resized.LockFocus(); image.DrawInRect(new CGRect(0, 0, inputWidth, inputHeight), CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); resized.UnlockFocus(); image.Dispose(); image = resized; } int[] intValues = new int[(int)(image.Size.Width * image.Size.Height)]; float[] floatValues = new float[(int)(image.Size.Width * image.Size.Height * 3)]; System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned); using (CGImage cgimage = image.CGImage) using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB()) using (CGBitmapContext context = new CGBitmapContext( handle.AddrOfPinnedObject(), (nint)image.Size.Width, (nint)image.Size.Height, 8, (nint)image.Size.Width * 4, cspace, CGImageAlphaInfo.PremultipliedLast )) { context.DrawImage(new CGRect(new CGPoint(), image.Size), cgimage); } handle.Free(); for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID || UNITY_STANDALONE Texture2D texture = ReadTexture2DFromFile(fileName); ReadTensorFromTexture2D <T>(texture, dest, inputHeight, inputWidth, inputMean, scale, flipUpSideDown, false); #else if (Emgu.TF.Util.Platform.OperationSystem == OS.Windows) { //Do something for Windows System.Drawing.Bitmap bmp = new Bitmap(fileName); if (inputHeight > 0 || inputWidth > 0) { //resize bmp System.Drawing.Bitmap newBmp = new Bitmap(bmp, inputWidth, inputHeight); bmp.Dispose(); bmp = newBmp; //bmp.Save("tmp.png"); } if (flipUpSideDown) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); } byte[] byteValues = new byte[bmp.Width * bmp.Height * 3]; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb, bd); Marshal.Copy(bd.Scan0, byteValues, 0, byteValues.Length); bmp.UnlockBits(bd); if (typeof(T) == typeof(float)) { int imageSize = bmp.Width * bmp.Height; float[] floatValues = new float[imageSize * 3]; if (swapBR) { for (int i = 0; i < imageSize; ++i) { floatValues[i * 3] = (byte)(((float)byteValues[i * 3 + 2] - inputMean) * scale); floatValues[i * 3 + 1] = (byte)(((float)byteValues[i * 3 + 1] - inputMean) * scale); floatValues[i * 3 + 2] = (byte)(((float)byteValues[i * 3 + 0] - inputMean) * scale); } } else { for (int i = 0; i < byteValues.Length; ++i) { floatValues[i] = ((float)byteValues[i] - inputMean) * scale; } } Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { if (swapBR) { int imageSize = bmp.Width * bmp.Height; //byte[] bValues = new byte[imageSize * 3]; for (int i = 0; i < imageSize; ++i) { byte c0 = (byte)(((float)byteValues[i * 3 + 2] - inputMean) * scale); byte c1 = (byte)(((float)byteValues[i * 3 + 1] - inputMean) * scale); byte c2 = (byte)(((float)byteValues[i * 3 + 0] - inputMean) * scale); byteValues[i * 3] = c0; byteValues[i * 3 + 1] = c1; byteValues[i * 3 + 2] = c2; } } else { if (!(inputMean == 0.0f && scale == 1.0f)) { for (int i = 0; i < byteValues.Length; ++i) { byteValues[i] = (byte)(((float)byteValues[i] - inputMean) * scale); } } } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new Exception(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } } else //Unix { if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } throw new Exception("Not implemented"); } #endif }
/// <summary> /// Read a NSImage, covert the data and save it to the native pointer /// </summary> /// <typeparam name="T">The type of the data to covert the image pixel values to. e.g. "float" or "byte"</typeparam> /// <param name="image">The input image</param> /// <param name="dest">The native pointer where the image pixels values will be saved to.</param> /// <param name="inputHeight">The height of the image, must match the height requirement for the tensor</param> /// <param name="inputWidth">The width of the image, must match the width requirement for the tensor</param> /// <param name="inputMean">The mean value, it will be subtracted from the input image pixel values</param> /// <param name="scale">The scale, after mean is subtracted, the scale will be used to multiply the pixel values</param> /// <param name="flipUpSideDown">If true, the image needs to be flipped up side down</param> /// <param name="swapBR">If true, will flip the Blue channel with the Red. e.g. If false, the tensor's color channel order will be RGB. If true, the tensor's color channle order will be BGR </param> public static void ReadImageToTensor <T>( NSImage image, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, bool flipUpSideDown = false, bool swapBR = false) where T : struct { if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } NSImage resized; if (inputHeight > 0 || inputWidth > 0) { resized = new NSImage(new CGSize(inputWidth, inputHeight)); resized.LockFocus(); image.DrawInRect(new CGRect(0, 0, inputWidth, inputHeight), CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); resized.UnlockFocus(); } else { resized = image; } int[] intValues = new int[(int)(resized.Size.Width * resized.Size.Height)]; float[] floatValues = new float[(int)(resized.Size.Width * resized.Size.Height * 3)]; System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned); using (CGImage cgimage = resized.CGImage) using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB()) using (CGBitmapContext context = new CGBitmapContext( handle.AddrOfPinnedObject(), (nint)resized.Size.Width, (nint)resized.Size.Height, 8, (nint)resized.Size.Width * 4, cspace, CGImageAlphaInfo.PremultipliedLast )) { context.DrawImage(new CGRect(new CGPoint(), resized.Size), cgimage); } handle.Free(); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } if (resized != image) { resized.Dispose(); } }
//- (NSImage *)thumbImageFromImage:(NSImage *)image; async Task<NSImage> ThumbImageFromImageAsync(NSImage image) { nfloat targetHeight = 200.0f; CGSize imageSize = image.Size; CGSize smallerSize = new CGSize(targetHeight * imageSize.Width / imageSize.Height, targetHeight); NSImage smallerImage = new NSImage(smallerSize); smallerImage.LockFocus(); image.DrawInRect(new CGRect(0,0,smallerSize.Width, smallerSize.Height), CGRect.Empty, NSCompositingOperation.Copy, 1.0f); smallerImage.UnlockFocus(); return smallerImage; }
public static void ReadImageFileToTensor(String fileName, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f) { #if __ANDROID__ Android.Graphics.Bitmap bmp = BitmapFactory.DecodeFile(fileName); if (inputHeight > 0 || inputWidth > 0) { Bitmap resized = Bitmap.CreateScaledBitmap(bmp, inputWidth, inputHeight, false); bmp.Dispose(); bmp = resized; } int[] intValues = new int[bmp.Width * bmp.Height]; float[] floatValues = new float[bmp.Width * bmp.Height * 3]; bmp.GetPixels(intValues, 0, bmp.Width, 0, 0, bmp.Width, bmp.Height); for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __IOS__ UIImage image = new UIImage(fileName); if (inputHeight > 0 || inputWidth > 0) { UIImage resized = image.Scale(new CGSize(inputWidth, inputHeight)); image.Dispose(); image = resized; } int[] intValues = new int[(int)(image.Size.Width * image.Size.Height)]; float[] floatValues = new float[(int)(image.Size.Width * image.Size.Height * 3)]; System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned); using (CGImage cgimage = image.CGImage) using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB()) using (CGBitmapContext context = new CGBitmapContext( handle.AddrOfPinnedObject(), (nint)image.Size.Width, (nint)image.Size.Height, 8, (nint)image.Size.Width * 4, cspace, CGImageAlphaInfo.PremultipliedLast )) { context.DrawImage(new CGRect(new CGPoint(), image.Size), cgimage); } handle.Free(); for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __UNIFIED__ NSImage image = new NSImage(fileName); if (inputHeight > 0 || inputWidth > 0) { NSImage resized = new NSImage(new CGSize(inputWidth, inputHeight)); resized.LockFocus(); image.DrawInRect(new CGRect(0, 0, inputWidth, inputHeight), CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); resized.UnlockFocus(); image.Dispose(); image = resized; } int[] intValues = new int[(int)(image.Size.Width * image.Size.Height)]; float[] floatValues = new float[(int)(image.Size.Width * image.Size.Height * 3)]; System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned); using (CGImage cgimage = image.CGImage) using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB()) using (CGBitmapContext context = new CGBitmapContext( handle.AddrOfPinnedObject(), (nint)image.Size.Width, (nint)image.Size.Height, 8, (nint)image.Size.Width * 4, cspace, CGImageAlphaInfo.PremultipliedLast )) { context.DrawImage(new CGRect(new CGPoint(), image.Size), cgimage); } handle.Free(); for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #else if (Emgu.TF.Util.Platform.OperationSystem == OS.Windows) { //Do something for Windows System.Drawing.Bitmap bmp = new Bitmap(fileName); if (inputHeight > 0 || inputWidth > 0) { //resize bmp System.Drawing.Bitmap newBmp = new Bitmap(bmp, inputWidth, inputHeight); bmp.Dispose(); bmp = newBmp; //bmp.Save("tmp.png"); } byte[] byteValues = new byte[bmp.Width * bmp.Height * 3]; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); bmp.LockBits( new Rectangle(0, 0, bmp.Width, bmp.Height), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb, bd); System.Runtime.InteropServices.Marshal.Copy(bd.Scan0, byteValues, 0, byteValues.Length); bmp.UnlockBits(bd); float[] floatValues = new float[bmp.Width * bmp.Height * 3]; for (int i = 0; i < byteValues.Length; ++i) { floatValues[i] = ((float)byteValues[i] - inputMean) * scale; } System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else { throw new Exception("Not implemented"); } #endif }
/// <summary> /// Read an image file, covert the data and save it to the native pointer /// </summary> /// <typeparam name="T">The type of the data to covert the image pixel values to. e.g. "float" or "byte"</typeparam> /// <param name="fileName">The name of the image file</param> /// <param name="dest">The native pointer where the image pixels values will be saved to.</param> /// <param name="inputHeight">The height of the image, must match the height requirement for the tensor</param> /// <param name="inputWidth">The width of the image, must match the width requirement for the tensor</param> /// <param name="inputMean">The mean value, it will be substracted from the input image pixel values</param> /// <param name="scale">The scale, after mean is substracted, the scale will be used to multiply the pixel values</param> /// <param name="flipUpSideDown">If true, the image needs to be flipped up side down</param> /// <param name="swapBR">If true, will flip the Blue channel with the Red. e.g. If false, the tensor's color channel order will be RGB. If true, the tensor's color channle order will be BGR </param> public static void ReadImageFileToTensor <T>( String fileName, IntPtr dest, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, bool flipUpSideDown = false, bool swapBR = false) where T : struct { if (!File.Exists(fileName)) { throw new FileNotFoundException(String.Format("File {0} do not exist.", fileName)); } #if __ANDROID__ Android.Graphics.Bitmap bmp = BitmapFactory.DecodeFile(fileName); if (inputHeight > 0 || inputWidth > 0) { Bitmap resized = Bitmap.CreateScaledBitmap(bmp, inputWidth, inputHeight, false); bmp.Dispose(); bmp = resized; } if (flipUpSideDown) { Matrix matrix = new Matrix(); matrix.PostScale(1, -1, bmp.Width / 2, bmp.Height / 2); Bitmap flipped = Bitmap.CreateBitmap(bmp, 0, 0, bmp.Width, bmp.Height, matrix, true); bmp.Dispose(); bmp = flipped; } int[] intValues = new int[bmp.Width * bmp.Height]; float[] floatValues = new float[bmp.Width * bmp.Height * 3]; bmp.GetPixels(intValues, 0, bmp.Width, 0, 0, bmp.Width, bmp.Height); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } #elif __IOS__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } UIImage image = new UIImage(fileName); if (inputHeight > 0 || inputWidth > 0) { UIImage resized = image.Scale(new CGSize(inputWidth, inputHeight)); image.Dispose(); image = resized; } int[] intValues = new int[(int)(image.Size.Width * image.Size.Height)]; float[] floatValues = new float[(int)(image.Size.Width * image.Size.Height * 3)]; System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned); using (CGImage cgimage = image.CGImage) using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB()) using (CGBitmapContext context = new CGBitmapContext( handle.AddrOfPinnedObject(), (nint)image.Size.Width, (nint)image.Size.Height, 8, (nint)image.Size.Width * 4, cspace, CGImageAlphaInfo.PremultipliedLast )) { context.DrawImage(new CGRect(new CGPoint(), image.Size), cgimage); } handle.Free(); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } //System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif __UNIFIED__ if (flipUpSideDown) { throw new NotImplementedException("Flip Up Side Down is Not implemented"); } //if (swapBR) // throw new NotImplementedException("swapBR is Not implemented"); NSImage image = new NSImage(fileName); if (inputHeight > 0 || inputWidth > 0) { NSImage resized = new NSImage(new CGSize(inputWidth, inputHeight)); resized.LockFocus(); image.DrawInRect(new CGRect(0, 0, inputWidth, inputHeight), CGRect.Empty, NSCompositingOperation.SourceOver, 1.0f); resized.UnlockFocus(); image.Dispose(); image = resized; } int[] intValues = new int[(int)(image.Size.Width * image.Size.Height)]; float[] floatValues = new float[(int)(image.Size.Width * image.Size.Height * 3)]; System.Runtime.InteropServices.GCHandle handle = System.Runtime.InteropServices.GCHandle.Alloc(intValues, System.Runtime.InteropServices.GCHandleType.Pinned); using (CGImage cgimage = image.CGImage) using (CGColorSpace cspace = CGColorSpace.CreateDeviceRGB()) using (CGBitmapContext context = new CGBitmapContext( handle.AddrOfPinnedObject(), (nint)image.Size.Width, (nint)image.Size.Height, 8, (nint)image.Size.Width * 4, cspace, CGImageAlphaInfo.PremultipliedLast )) { context.DrawImage(new CGRect(new CGPoint(), image.Size), cgimage); } handle.Free(); if (swapBR) { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = ((val & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = (((val >> 16) & 0xFF) - inputMean) * scale; } } else { for (int i = 0; i < intValues.Length; ++i) { int val = intValues[i]; floatValues[i * 3 + 0] = (((val >> 16) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 1] = (((val >> 8) & 0xFF) - inputMean) * scale; floatValues[i * 3 + 2] = ((val & 0xFF) - inputMean) * scale; } } if (typeof(T) == typeof(float)) { Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { //copy float to bytes byte[] byteValues = new byte[floatValues.Length]; for (int i = 0; i < floatValues.Length; i++) { byteValues[i] = (byte)floatValues[i]; } Marshal.Copy(byteValues, 0, dest, byteValues.Length); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } //System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, dest, floatValues.Length); #elif UNITY_EDITOR || UNITY_IOS || UNITY_ANDROID || UNITY_STANDALONE Texture2D texture = ReadTexture2DFromFile(fileName); ReadTensorFromTexture2D <T>(texture, dest, inputHeight, inputWidth, inputMean, scale, flipUpSideDown, false); #else //if (System.Runtime.InteropServices.RuntimeInformation.IsOSPlatform(System.Runtime.InteropServices.OSPlatform.Windows)) { //Read the file using Bitmap class System.Drawing.Bitmap bmp = new Bitmap(fileName); if (inputHeight > 0 || inputWidth > 0) { //resize bmp System.Drawing.Bitmap newBmp = new Bitmap(bmp, inputWidth, inputHeight); bmp.Dispose(); bmp = newBmp; //bmp.Save("tmp.png"); } if (flipUpSideDown) { bmp.RotateFlip(RotateFlipType.RotateNoneFlipY); } int bmpWidth = bmp.Width; int bmpHeight = bmp.Height; System.Drawing.Imaging.BitmapData bd = new System.Drawing.Imaging.BitmapData(); bmp.LockBits( new Rectangle(0, 0, bmpWidth, bmpHeight), System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb, bd); int stride = bd.Stride; byte[] byteValues = new byte[bmpHeight * stride]; Marshal.Copy(bd.Scan0, byteValues, 0, byteValues.Length); bmp.UnlockBits(bd); if (typeof(T) == typeof(float)) { int imageSize = bmpWidth * bmpHeight; float[] floatValues = new float[imageSize * 3]; if (swapBR) { int idx = 0; int rowOffset = 0; for (int i = 0; i < bmpHeight; ++i) { int rowPtr = rowOffset; for (int j = 0; j < bmpWidth; ++j) { float b = ((float)byteValues[rowPtr++] - inputMean) * scale; float g = ((float)byteValues[rowPtr++] - inputMean) * scale; float r = ((float)byteValues[rowPtr++] - inputMean) * scale; floatValues[idx++] = r; floatValues[idx++] = g; floatValues[idx++] = b; } rowOffset += stride; } } else { int idx = 0; int rowOffset = 0; for (int i = 0; i < bmpHeight; ++i) { int rowPtr = rowOffset; for (int j = 0; j < bmpWidth; ++j) { floatValues[idx++] = ((float)byteValues[rowPtr++] - inputMean) * scale; floatValues[idx++] = ((float)byteValues[rowPtr++] - inputMean) * scale; floatValues[idx++] = ((float)byteValues[rowPtr++] - inputMean) * scale; } rowOffset += stride; } } Marshal.Copy(floatValues, 0, dest, floatValues.Length); } else if (typeof(T) == typeof(byte)) { int imageSize = bmp.Width * bmp.Height; if (swapBR) { int idx = 0; for (int i = 0; i < bmpHeight; ++i) { int offset = i * stride; for (int j = 0; j < bmpWidth; ++j) { byte b = (byte)(((float)byteValues[offset++] - inputMean) * scale); byte g = (byte)(((float)byteValues[offset++] - inputMean) * scale); byte r = (byte)(((float)byteValues[offset++] - inputMean) * scale); byteValues[idx++] = r; byteValues[idx++] = g; byteValues[idx++] = b; } } } else { int idx = 0; for (int i = 0; i < bmpHeight; ++i) { int offset = i * stride; for (int j = 0; j < bmpWidth * 3; ++j) { byteValues[idx++] = (byte)(((float)byteValues[offset++] - inputMean) * scale); } } } Marshal.Copy(byteValues, 0, dest, imageSize * 3); } else { throw new NotImplementedException(String.Format("Destination data type {0} is not supported.", typeof(T).ToString())); } } /* * else //Unix * { * //if (flipUpSideDown) * // throw new NotImplementedException("Flip Up Side Down is Not implemented"); * * throw new NotImplementedException("Not implemented"); * }*/ #endif }