internal static BitmapFrame ToBitmapFrame(this Image image) { // calculate pixel format System.Windows.Media.PixelFormat pixelFormat = PixelFormats.Indexed1; switch (image.BitsPerPixel) { case 1: pixelFormat = PixelFormats.Indexed1; break; case 2: pixelFormat = PixelFormats.Indexed2; break; case 4: pixelFormat = PixelFormats.Indexed4; break; case 8: pixelFormat = PixelFormats.Indexed8; break; case 32: pixelFormat = PixelFormats.Bgr32; break; default: throw new NotImplementedException( string.Format(CultureInfo.InvariantCulture, Properties.Resources.E_UnsupportedDepth, image.BitsPerPixel)); } // get palette BitmapPalette bitmapPalette = null; Color[] palette = Image.CreatePalette(image.BitsPerPixel); if (palette != null) { bitmapPalette = new BitmapPalette(palette.Select(x => System.Windows.Media.Color.FromArgb(x.A, x.R, x.G, x.B)).ToArray()); } WriteableBitmap bitmapSource = new WriteableBitmap( image.Width, image.Height, image.HorizontalResolution, image.VerticalResolution, pixelFormat, bitmapPalette); System.Windows.Int32Rect sourceRect = new System.Windows.Int32Rect(0, 0, image.Width, image.Height); if (image.BitsPerPixel < 8) { // swap bits to make storage big-endian ulong[] bits = new ulong[image.Bits.Length]; Vectors.SwapBits(image.Bits.Length, image.Bits, 0, image.BitsPerPixel, bits, 0); bitmapSource.WritePixels(sourceRect, bits, image.Stride8, 0); } else { bitmapSource.WritePixels(sourceRect, image.Bits, image.Stride8, 0); } return(BitmapFrame.Create(bitmapSource)); }
/// <summary> /// Converts this <see cref="Image"/> to a <see cref="System.Drawing.Bitmap"/>. /// </summary> /// <param name="image">The <see cref="Image"/> from which to create the GDI+ bitmap.</param> /// <returns> /// A <see cref="System.Drawing.Bitmap"/> that represents the converted <see cref="Image"/>. /// </returns> public static System.Drawing.Bitmap ToBitmap(this Image image) { if (image == null) { throw new ArgumentNullException(nameof(image)); } // select pixel format System.Drawing.Imaging.PixelFormat pixelFormat = BitmapExtensions.BitsPerPixelToPixelFormat(image.BitsPerPixel); // create new bitmap System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(image.Width, image.Height, pixelFormat); try { bitmap.SetResolution(image.HorizontalResolution, image.VerticalResolution); // copy bits BitmapData dstData = bitmap.LockBits( new System.Drawing.Rectangle(0, 0, image.Width, image.Height), ImageLockMode.WriteOnly, pixelFormat); unsafe { fixed(ulong *src = image.Bits) { Arrays.CopyStrides( image.Height, new IntPtr(src), image.Stride8, dstData.Scan0, dstData.Stride); if (image.BitsPerPixel < 8) { IntPtr dst = dstData.Scan0; if (dstData.Stride < 0) { dst = IntPtr.Add(dst, (image.Height - 1) * dstData.Stride); } Vectors.SwapBits( image.Height * Math.Abs(dstData.Stride) / sizeof(uint), image.BitsPerPixel, (uint *)dst.ToPointer()); } } } bitmap.UnlockBits(dstData); // we need to set palette for binary and gray scale images // as our color map is different from default map used by System.Drawing.Bitmap if (image.BitsPerPixel <= 8 && bitmap.Palette != null) { Color[] palette = Image.CreatePalette(image.BitsPerPixel); ColorPalette dst = bitmap.Palette; if (dst.Entries.Length == palette.Length) { for (int i = 0, ii = palette.Length; i < ii; i++) { dst.Entries[i] = System.Drawing.Color.FromArgb((int)palette[i].Argb); } } // we need to reset the palette as the getter returns its clone bitmap.Palette = dst; } return(bitmap); } catch { bitmap.Dispose(); throw; } }