示例#1
2
        public static Bitmap Binarize(Bitmap bm, double threshhold)
        {
            //Binarize
            int size = bm.Width * bm.Height;
            int[] pixels = new int[size];
            bm.GetPixels( pixels, 0, bm.Width, 0, 0, bm.Width, bm.Height );

            // Calculate overall lightness of image
            int c;
            for (int i = 0; i < size; i++)
            {
                c = pixels[i];
                double whiteDist = Math.Sqrt(Math.Pow(0xff - ((c&0x00FF0000 )>>16),2) + Math.Pow(0xff - ((c & 0x0000FF00 )>>8), 2) + Math.Pow(0xff - (c&0x000000FF), 2));
                double blackDist = Math.Sqrt(Math.Pow(0x00 - ((c&0x00FF0000 )>>16),2) + Math.Pow(0x00 - ((c & 0x0000FF00 )>>8), 2) + Math.Pow(0x00 - (c&0x000000FF), 2));
                double distance = blackDist + whiteDist;

                if (whiteDist / distance > threshhold / 30.0) {
                    pixels [i] = Color.Black;
                } else {
                    pixels [i] = Color.White;
                }
            }

            Bitmap newBitmap = bm.Copy (bm.GetConfig (), true);
            newBitmap.SetPixels (pixels, 0, bm.Width, 0, 0, bm.Width, bm.Height);

            return newBitmap;
        }
示例#2
0
 /// <summary>
 /// Convert a Bitmap to and from this Mat
 /// </summary>
 /// <param name="mat">The mat to copy Bitmap into</param>
 /// <param name="bitmap">The bitmap to copy into mat</param>
 public static void SetBitmap(this Mat mat, Android.Graphics.Bitmap bitmap)
 {
     Android.Graphics.Bitmap.Config config = bitmap.GetConfig();
     if (config.Equals(Android.Graphics.Bitmap.Config.Argb8888))
     {
         using (BitmapArgb8888Image bi = new BitmapArgb8888Image(bitmap))
         {
             CvInvoke.CvtColor(bi, mat, ColorConversion.Rgba2Bgra);
         }
     }
     else if (config.Equals(Android.Graphics.Bitmap.Config.Rgb565))
     {
         Size  size   = new Size(bitmap.Width, bitmap.Height);
         int[] values = new int[size.Width * size.Height];
         bitmap.GetPixels(values, 0, size.Width, 0, 0, size.Width, size.Height);
         GCHandle handle = GCHandle.Alloc(values, GCHandleType.Pinned);
         using (Mat bgra = new Mat(size, DepthType.Cv8U, 4, handle.AddrOfPinnedObject(), size.Width * 4))
         {
             bgra.CopyTo(mat);
         }
         handle.Free();
     }
     else
     {
         throw new NotImplementedException(String.Format("Coping from Bitmap of {0} is not implemented", config));
     }
 }
        private static Bitmap ChangeColor(Bitmap bitmap, Color fromColor, Color targetColor, float tolerance = 20)
        {
            int width = bitmap.Width;
            int height = bitmap.Height;
            int[] pixels = new int[width * height];

            float[] redRange = new float[2]{
                (float)Math.Max(fromColor.R - (tolerance / 2), 0.0),
                (float)Math.Min(fromColor.R + (tolerance / 2), 255.0)};

            float[] greenRange = new float[2]{
                (float)Math.Max(fromColor.G - (tolerance / 2), 0.0),
                (float)Math.Min(fromColor.G + (tolerance / 2), 255.0)};

            float[] blueRange = new float[2]{
                (float)Math.Max(fromColor.B - (tolerance / 2), 0.0),
                (float)Math.Min(fromColor.B + (tolerance / 2), 255.0)};

            bitmap.GetPixels(pixels, 0, width, 0, 0, width, height);

            for (int i = 0; i < pixels.Length; i++)
            {

                if (pixels[i] == fromColor)
                {
                    pixels[i] = new Color(targetColor.R, targetColor.G, targetColor.B, targetColor.A - 1);
                }

                int red = Color.GetRedComponent(pixels[i]);
                int green = Color.GetGreenComponent(pixels[i]);
                int blue = Color.GetBlueComponent(pixels[i]);
                int alpha = Color.GetAlphaComponent(pixels[i]);

                if (((red >= redRange[0]) && (red <= redRange[1])) &&
                    ((green >= greenRange[0]) && (green <= greenRange[1])) &&
                    ((blue >= blueRange[0]) && (blue <= blueRange[1])) &&
                    ((alpha > 0 && alpha < 254)))
                {
                    pixels[i] = new Color(targetColor.R, targetColor.G, targetColor.B, targetColor.A - 1);
                }
            }

            if (bitmap.IsMutable)
            {
                bitmap.SetPixels(pixels, 0, width, 0, 0, width, height);
                return bitmap;
            }
            else
            {
                var mutableBitmap = bitmap.Copy(bitmap.GetConfig(), true);
                mutableBitmap.SetPixels(pixels, 0, width, 0, 0, width, height);
                return mutableBitmap;
            }
        }
 /// <summary>
 /// Initializes a new instance of the <see cref="BitmapLuminanceSource"/> class.
 /// </summary>
 /// <param name="bitmap">The bitmap.</param>
 public BitmapLuminanceSource(Bitmap bitmap)
    : base(bitmap.Width, bitmap.Height)
 {
    // get all pixels at once from the bitmap (should be one of the fastest ways to analyze the whole picture)
    var pixels = new int[bitmap.Width * bitmap.Height];
    bitmap.GetPixels(pixels, 0, bitmap.Width, 0, 0, bitmap.Width, bitmap.Height);
    // convert the pixel array to a byte array because the underlying method of 
    // RGBLuminanceSource doesn't support an int array
    var pixelBytes = new byte[pixels.Length * 4];
    Buffer.BlockCopy(pixels, 0, pixelBytes, 0, pixelBytes.Length);
    // calculating the luminance values the same way as RGBLuminanceSource
    CalculateLuminance(pixelBytes, BitmapFormat.RGB32);
 }
示例#5
0
        //#region Conversion with Bitmap
        /// <summary>
        /// The Get property provide a more efficient way to convert Image&lt;Gray, Byte&gt;, Image&lt;Bgr, Byte&gt; and Image&lt;Bgra, Byte&gt; into Bitmap
        /// such that the image data is <b>shared</b> with Bitmap.
        /// If you change the pixel value on the Bitmap, you change the pixel values on the Image object as well!
        /// For other types of image this property has the same effect as ToBitmap()
        /// <b>Take extra caution not to use the Bitmap after the Image object is disposed</b>
        /// The Set property convert the bitmap to this Image type.
        /// </summary>
        public static Image <TColor, TDepth> ToImage <TColor, TDepth>(this Bitmap bitmap)
            where TColor : struct, IColor
            where TDepth : new()
        {
            #region reallocate memory if necessary
            Size size = new Size(bitmap.Width, bitmap.Height);
            Image <TColor, TDepth> image = new Image <TColor, TDepth>(size);

            /*
             * if (image.Ptr == IntPtr.Zero)
             * {
             *  image.AllocateData(size.Height, size.Width, image.NumberOfChannels);
             * }
             * else if (!Size.Equals(size))
             * {
             *  image.DisposeObject();
             *  image.AllocateData(size.Height, size.Width, image.NumberOfChannels);
             * }*/
            #endregion

            Android.Graphics.Bitmap.Config config = bitmap.GetConfig();
            if (config.Equals(Android.Graphics.Bitmap.Config.Argb8888))
            {
                using (BitmapArgb8888Image bi = new BitmapArgb8888Image(bitmap))
                {
                    image.ConvertFrom(bi);
                }
            }
            else if (config.Equals(Android.Graphics.Bitmap.Config.Rgb565))
            {
                int[] values = new int[size.Width * size.Height];
                bitmap.GetPixels(values, 0, size.Width, 0, 0, size.Width, size.Height);
                GCHandle handle = GCHandle.Alloc(values, GCHandleType.Pinned);
                using (Image <Bgra, Byte> bgra = new Image <Bgra, byte>(size.Width, size.Height, size.Width * 4, handle.AddrOfPinnedObject()))
                {
                    image.ConvertFrom(bgra);
                }
                handle.Free();
            }
            else
            {
                throw new NotImplementedException(String.Format("Coping from Bitmap of {0} is not implemented", config));
            }

            return(image);
        }
 private static Bitmap CreateOverlayedBitmap(Bitmap bitmap, int width, int height)
 {
     int[] originalPixels = new int[bitmap.Width * bitmap.Height];
     bitmap.GetPixels(originalPixels, 0, bitmap.Width, 0, 0, bitmap.Width, bitmap.Height);
     int[] pixels = new int[width * height];
     int xStart = (width - bitmap.Width) / 2;
     int xEnd = (width + bitmap.Width) / 2;
     for (int y = 0; y < height; y++)
     {
         int rowStart = y*width;
         int originalRowStart = y*bitmap.Width;
         for (int ox = 0, x = xStart; x < xEnd; x++, ox++)
         {
             pixels[rowStart + x] = originalPixels[originalRowStart + ox];
         }
     }
     return Bitmap.CreateBitmap(pixels, width, height, bitmap.GetConfig());
 }
        Bitmap RGB565toARGB888(Bitmap img)
        {
            int numPixels = img.Width * img.Height;

            //Create a Bitmap of the appropriate format.
            if (tmp == null)
            {
                tmp = Bitmap.CreateBitmap(img.Width, img.Height, Bitmap.Config.Argb8888);
                pixels = new int[numPixels];
            }

            //Get JPEG pixels.  Each int is the color values for one pixel.
            img.GetPixels(pixels, 0, img.Width, 0, 0, img.Width, img.Height);

            //Set RGB pixels.
            tmp.SetPixels(pixels, 0, tmp.Width, 0, 0, tmp.Width, tmp.Height);

            return tmp;
        }
示例#8
0
        // This code is a C# port of the Java code which can be found at:
        // http://www.java2s.com/Code/Android/2D-Graphics/Generateablurredbitmapfromgivenone.htm
        //
        // The following code is another example (Java based):
        // http://incubator.quasimondo.com/processing/stackblur.pde
        public Bitmap GetBlurredBitmap(Bitmap original, int radius)
        {
            if (radius < 1)
            {
                throw new ArgumentOutOfRangeException("radius", "Radius must be > =1.");
            }

            int width = original.Width;
            int height = original.Height;
            int wm = width - 1;
            int hm = height - 1;
            int wh = width * height;
            int div = radius + radius + 1;
            int[] r = new int[wh];
            int[] g = new int[wh];
            int[] b = new int[wh];
            int rsum, gsum, bsum, x, y, i;
            int p1, p2;
            int[] vmin = new int[Math.Max(width, height)];
            int[] vmax = new int[Math.Max(width, height)];
            int[] dv = new int[256 * div];
            for (i = 0; i < 256 * div; i++)
            {
                dv[i] = i / div;
            }

            int[] blurredBitmap = new int[wh];
            original.GetPixels(blurredBitmap, 0, width, 0, 0, width, height);
            int yw = 0;
            int yi = 0;

            for (y = 0; y < height; y++)
            {
                rsum = 0;
                gsum = 0;
                bsum = 0;
                for (i = -radius; i <= radius; i++)
                {
                    int p = blurredBitmap[yi + Math.Min(wm, Math.Max(i, 0))];
                    rsum += (p & 0xff0000) >> 16;
                    gsum += (p & 0x00ff00) >> 8;
                    bsum += p & 0x0000ff;
                }
                for (x = 0; x < width; x++)
                {
                    r[yi] = dv[rsum];
                    g[yi] = dv[gsum];
                    b[yi] = dv[bsum];

                    if (y == 0)
                    {
                        vmin[x] = Math.Min(x + radius + 1, wm);
                        vmax[x] = Math.Max(x - radius, 0);
                    }
                    p1 = blurredBitmap[yw + vmin[x]];
                    p2 = blurredBitmap[yw + vmax[x]];

                    rsum += ((p1 & 0xff0000) - (p2 & 0xff0000)) >> 16;
                    gsum += ((p1 & 0x00ff00) - (p2 & 0x00ff00)) >> 8;
                    bsum += (p1 & 0x0000ff) - (p2 & 0x0000ff);
                    yi++;
                }
                yw += width;
            }

            for (x = 0; x < width; x++)
            {
                rsum = gsum = bsum = 0;
                int yp = -radius * width;
                for (i = -radius; i <= radius; i++)
                {
                    yi = Math.Max(0, yp) + x;
                    rsum += r[yi];
                    gsum += g[yi];
                    bsum += b[yi];
                    yp += width;
                }
                yi = x;
                for (y = 0; y < height; y++)
                {
                    blurredBitmap[yi] = (int)(0xff000000 | (dv[rsum] << 16) | (dv[gsum] << 8) | dv[bsum]);
                    if (x == 0)
                    {
                        vmin[y] = Math.Min(y + radius + 1, hm) * width;
                        vmax[y] = Math.Max(y - radius, 0) * width;
                    }
                    p1 = x + vmin[y];
                    p2 = x + vmax[y];

                    rsum += r[p1] - r[p2];
                    gsum += g[p1] - g[p2];
                    bsum += b[p1] - b[p2];

                    yi += width;
                }
            }

            Bitmap.Config config = Bitmap.Config.Rgb565;
            return Bitmap.CreateBitmap(blurredBitmap, width, height, config);
        }
示例#9
0
        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
        }
示例#10
0
        public static Tensor ReadTensorFromImageFile(String fileName, int inputHeight = -1, int inputWidth = -1, float inputMean = 0.0f, float scale = 1.0f, Status status = null)
        {
#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;
            }

            Tensor t = new Tensor(DataType.Float, new int[] { 1, bmp.Height, bmp.Width, 3 });
            System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, t.DataPointer, floatValues.Length);
            return(t);
#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;
            }

            Tensor t = new Tensor(DataType.Float, new int[] { 1, (int)image.Size.Height, (int)image.Size.Width, 3 });
            System.Runtime.InteropServices.Marshal.Copy(floatValues, 0, t.DataPointer, floatValues.Length);
            return(t);
#else
            if (Emgu.TF.Util.Platform.OperationSystem == OS.Windows)
            {
                Tensor t = new Tensor(DataType.Float, new int[] { 1, (int)inputHeight, (int)inputWidth, 3 });
                NativeImageIO.ReadImageFileToTensor(fileName, t.DataPointer, inputHeight, inputWidth, inputMean, scale);
                return(t);
            }
            else
            {
                using (StatusChecker checker = new StatusChecker(status))
                {
                    var       graph = new Graph();
                    Operation input = graph.Placeholder(DataType.String);

                    Operation jpegDecoder = graph.DecodeJpeg(input, 3);                    //dimension 3

                    Operation floatCaster = graph.Cast(jpegDecoder, DstT: DataType.Float); //cast to float

                    Tensor    axis         = new Tensor(0);
                    Operation axisOp       = graph.Const(axis, axis.Type, opName: "axis");
                    Operation dimsExpander = graph.ExpandDims(floatCaster, axisOp); //turn it to dimension [1,3]

                    Operation resized;
                    bool      resizeRequired = (inputHeight > 0) && (inputWidth > 0);
                    if (resizeRequired)
                    {
                        Tensor    size   = new Tensor(new int[] { inputHeight, inputWidth }); // new size;
                        Operation sizeOp = graph.Const(size, size.Type, opName: "size");
                        resized = graph.ResizeBilinear(dimsExpander, sizeOp);                 //resize image
                    }
                    else
                    {
                        resized = dimsExpander;
                    }

                    Tensor    mean        = new Tensor(inputMean);
                    Operation meanOp      = graph.Const(mean, mean.Type, opName: "mean");
                    Operation substracted = graph.Sub(resized, meanOp);

                    Tensor    scaleTensor = new Tensor(scale);
                    Operation scaleOp     = graph.Const(scaleTensor, scaleTensor.Type, opName: "scale");
                    Operation scaled      = graph.Mul(substracted, scaleOp);

                    Session  session      = new Session(graph);
                    Tensor   imageTensor  = Tensor.FromString(File.ReadAllBytes(fileName), status);
                    Tensor[] imageResults = session.Run(new Output[] { input }, new Tensor[] { imageTensor },
                                                        new Output[] { scaled });
                    return(imageResults[0]);
                }
            }
#endif
        }
示例#11
0
        /// <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 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 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));
            }

            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()));
            }
        }
示例#12
0
        public static void Blur(Bitmap original, Bitmap blurred, int radius)
        {
            if (radius < 1)
            {
                throw new ArgumentOutOfRangeException("radius", "Radius must be > 0.");
            }

            int width = original.Width;
            int height = original.Height;
            int wm = width - 1;
            int hm = height - 1;
            int wh = width * height;
            int div = radius + radius + 1;
            int[] a = new int[wh];
            int[] r = new int[wh];
            int[] g = new int[wh];
            int[] b = new int[wh];
            int asum, rsum, gsum, bsum;
            int x, y, i;
            int p1, p2;
            int[] vmin = new int[Math.Max(width, height)];
            int[] vmax = new int[Math.Max(width, height)];
            int[] dv = new int[256 * div];
            for (i = 0; i < 256 * div; i++)
            {
                dv[i] = i / div;
            }

            int[] blurredBitmap = new int[wh];
            original.GetPixels(blurredBitmap, 0, width, 0, 0, width, height);
            Premultiply(blurredBitmap);

            int yw = 0;
            int yi = 0;

            for (y = 0; y < height; y++)
            {
                asum = 0;
                rsum = 0;
                gsum = 0;
                bsum = 0;
                for (i = -radius; i <= radius; i++)
                {
                    int p = blurredBitmap[yi + Math.Min(wm, Math.Max(i, 0))];
                    asum += A(p);
                    rsum += R(p);
                    gsum += G(p);
                    bsum += B(p);
                }
                for (x = 0; x < width; x++)
                {
                    a[yi] = dv[asum];
                    r[yi] = dv[rsum];
                    g[yi] = dv[gsum];
                    b[yi] = dv[bsum];

                    if (y == 0)
                    {
                        vmin[x] = Math.Min(x + radius + 1, wm);
                        vmax[x] = Math.Max(x - radius, 0);
                    }
                    p1 = blurredBitmap[yw + vmin[x]];
                    p2 = blurredBitmap[yw + vmax[x]];

                    asum += A(p1) - A(p2);
                    rsum += R(p1) - R(p2);
                    gsum += G(p1) - G(p2);
                    bsum += B(p1) - B(p2);

                    yi++;
                }
                yw += width;
            }

            for (x = 0; x < width; x++)
            {
                asum = rsum = gsum = bsum = 0;
                int yp = -radius * width;
                for (i = -radius; i <= radius; i++)
                {
                    yi = Math.Max(0, yp) + x;
                    asum += a[yi];
                    rsum += r[yi];
                    gsum += g[yi];
                    bsum += b[yi];
                    yp += width;
                }
                yi = x;
                for (y = 0; y < height; y++)
                {
                    blurredBitmap[yi] = (dv[asum] << 24) | (dv[rsum] << 16) | (dv[gsum] << 8) | (dv[bsum]);
                    if (x == 0)
                    {
                        vmin[y] = Math.Min(y + radius + 1, hm) * width;
                        vmax[y] = Math.Max(y - radius, 0) * width;
                    }
                    p1 = x + vmin[y];
                    p2 = x + vmax[y];

                    asum += a[p1] - a[p2];
                    rsum += r[p1] - r[p2];
                    gsum += g[p1] - g[p2];
                    bsum += b[p1] - b[p2];

                    yi += width;
                }
            }

            Unpremultiply(blurredBitmap);
            blurred.SetPixels(blurredBitmap, 0, width, 0, 0, width, height);
        }
示例#13
0
        // WHAT IS THE DEFAULT FONT FOR ANDROID?
                #endif

        // Partial class implementation of draw() in c# to allow use of unsafe code..
        public unsafe void draw(IBitmapDrawable source, flash.geom.Matrix matrix = null, ColorTransform colorTransform = null, string blendMode = null,
                                Rectangle clipRect = null, Boolean smoothing = false)
        {
                        #if PLATFORM_MONOMAC || PLATFORM_MONOTOUCH
            if (source is flash.text.TextField)
            {
                flash.text.TextField  tf     = source as flash.text.TextField;
                flash.text.TextFormat format = tf.defaultTextFormat;

                // $$TODO figure out how to get rid of this extra data copy
                var sizeToDraw = (width * height) << 2;
                if (sizeToDraw == 0)
                {
                    return;
                }

                string fontName = format.font;
                float  fontSize = (format.size is double) ? (float)(double)format.size : ((format.size is int) ? (float)(int)format.size : 10);

                // Check if the font is installed?
                bool hasFont = true;
                if (!sHasFont.TryGetValue(fontName, out hasFont))
                {
                                        #if PLATFORM_MONOTOUCH
                    UIFont font = UIFont.FromName(fontName, 10);

                    sHasFont[fontName] = hasFont = font != null;
                    if (font != null)
                    {
                        font.Dispose();
                    }
                                        #elif PLATFORM_MONOMAC
                    NSFont font = NSFont.FromFontName(fontName, 10);

                    sHasFont[fontName] = hasFont = font != null;
                    if (font != null)
                    {
                        font.Dispose();
                    }
                                        #else
                    sHasFont[fontName] = false;
                                        #endif
                }
                if (!hasFont)
                {
                    fontName = DEFAULT_FONT;
                }

                fixed(uint *data = mData)
                {
                    using (CGBitmapContext context = new CGBitmapContext(new IntPtr(data), width, height, 8, 4 * width,
                                                                         CGColorSpace.CreateDeviceRGB(),
                                                                         CGImageAlphaInfo.PremultipliedLast))
                    {
                        uint    tfColor = format.color != null ? (uint)(format.color) : 0;
                        float   r       = (float)((tfColor >> 16) & 0xFF) / 255.0f;
                        float   g       = (float)((tfColor >> 8) & 0xFF) / 255.0f;
                        float   b       = (float)((tfColor >> 0) & 0xFF) / 255.0f;
                        float   a       = (float)(tf.alpha);
                        CGColor color   = new CGColor(r, g, b, a);
                        context.SetFillColor(color);
                        context.SetStrokeColor(color);
                        context.SelectFont(fontName, fontSize, CGTextEncoding.MacRoman);
                        context.SetAllowsAntialiasing(((tf.antiAliasType as string) == flash.text.AntiAliasType.ADVANCED));

                        double x = matrix.tx;
                        double y = matrix.ty;

                        // invert y because the CG origin is bottom,left
                        y = height - tf.textHeight - y;

                        // align text
                        switch (format.align)
                        {
                        case TextFormatAlign.LEFT:
                            // no adjustment required
                            break;

                        case TextFormatAlign.CENTER:
                            // center x
                            x += width / 2;
                            x -= tf.textWidth / 2;
                            break;

                        case TextFormatAlign.RIGHT:
                            // right justify x
                            x += width;
                            x -= tf.textWidth;
                            break;

                        default:
                            throw new System.NotImplementedException();
                        }

                        // draw text
                        context.ShowTextAtPoint((float)x, (float)y, tf.text);
                    }
                }
            }
            else
                                #elif PLATFORM_MONODROID
            if (source is flash.text.TextField)
            {
                flash.text.TextField  tf     = source as flash.text.TextField;
                flash.text.TextFormat format = tf.defaultTextFormat;

                // $$TODO figure out how to get rid of this extra data copy
                var data = new byte[width * height * 4];
                System.Buffer.BlockCopy(mData, 0, data, 0, data.Length);

                Android.Graphics.Bitmap.Config config = Android.Graphics.Bitmap.Config.Argb8888;
                Android.Graphics.Bitmap        bitmap = Android.Graphics.Bitmap.CreateBitmap(width, height, config);

                Canvas canvas = new Canvas(bitmap);
                var    x      = matrix.tx;
                var    y      = matrix.ty;

                // invert y because the CG origin is bottom,left
                // y = height - tf.textHeight - y;

                // align text
                switch (format.align)
                {
                case TextFormatAlign.LEFT:
                    // no adjustment required
                    break;

                case TextFormatAlign.CENTER:
                    // center x
                    x += width / 2;
                    x -= tf.textWidth / 2;
                    break;

                case TextFormatAlign.RIGHT:
                    // right justify x
                    x += width;
                    x -= tf.textWidth;
                    break;

                default:
                    throw new System.NotImplementedException();
                }

                Paint paint = new Paint(PaintFlags.AntiAlias);

                paint.Color    = Color.Black;
                paint.TextSize = (float)format.size;
                paint.SetTypeface(Typeface.Create(format.font, TypefaceStyle.Normal));
                paint.TextAlign = Paint.Align.Center;

                canvas.DrawText(tf.text, (float)x, (float)y, paint);

                mData = new uint[bitmap.Width * bitmap.Height];
                var buffer = new int[bitmap.Width * bitmap.Height];
                bitmap.GetPixels(buffer, 0, width, 0, 0, width, height);

                for (int i = 0; i < buffer.Length; i++)
                {
                    mData[i] = (uint)buffer[i];
                }
            }

            else
                                #endif
            if (source is flash.display.BitmapData)
            {
                //naive implementation ,
                //to be implemented:
                // -smoothing / antialiasing,
                // -blend mode
                // -colorTransform
                // -cliprect
                BitmapData        sourceBitmap = source as BitmapData;
                flash.geom.Matrix matInverse   = (matrix != null) ? matrix.clone() : new flash.geom.Matrix();
                matInverse.invert();

                for (int y = 0; y < mHeight; y++)
                {
                    for (int x = 0; x < mWidth; x++)
                    {
                        int x2 = (int)(x * matInverse.a + y * matInverse.c + matInverse.tx);
                        int y2 = (int)(x * matInverse.b + y * matInverse.d + matInverse.ty);
                        if (x2 >= 0 && y2 >= 0 && x2 < sourceBitmap.width && y2 < sourceBitmap.height)
                        {
                            mData[x + y * mWidth] = sourceBitmap.mData[x2 + y2 * sourceBitmap.mWidth];
                        }
                    }
                }
            }
            else
            {
                _root.trace_fn.trace("NotImplementedWarning: BitmapData.draw()");
            }
        }
示例#14
0
        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
        }
示例#15
0
        /// <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
        }