public static void ToBitmap(this InteropBitmap img, System.Drawing.Bitmap bmp) { if (img == null) return; int imgW = img.PixelWidth; int imgH = img.PixelHeight; byte[] byte_arr = new byte[(int)(4 * img.PixelWidth * img.PixelHeight)]; int stride = ((img.PixelWidth * img.Format.BitsPerPixel + 31) & ~31) >> 3; img.CopyPixels(byte_arr, stride, 0); System.Drawing.Imaging.BitmapData bData; //The Width and Height should be static don't bother depending on the //InteropBitmap for them if (imgW == -1 || imgH == -1) { imgW = (int)img.PixelWidth; imgH = (int)img.PixelHeight; } bData = bmp.LockBits(new System.Drawing.Rectangle(new System.Drawing.Point(), bmp.Size), System.Drawing.Imaging.ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); Marshal.Copy(byte_arr, 0, bData.Scan0, byte_arr.Length); bmp.UnlockBits(bData); }
public static BitmapSource ClipBitmapSource(this BitmapSource bs, int x, int y, int width, int height) { var rect = new Int32Rect(x, y, width, height); var stride = bs.Format.BitsPerPixel * rect.Width / 8; byte[] data = new byte[rect.Height * stride]; bs.CopyPixels(rect, data, stride, 0); return BitmapSource.Create(width, height, 0, 0, System.Windows.Media.PixelFormats.Bgra32, null, data, stride); }
public static byte[] GetPixels(this BitmapSource bitmap, int stride) { var result = new byte[bitmap.PixelHeight * stride]; bitmap.CopyPixels(result, stride, 0); return result; }
public static byte[] GetLineBytes(this BitmapSource image, int line) { //TODO: проверки на line byte[] bytes = new byte[image.PixelWidth * Constants.BytesPerPixel]; var stride = image.PixelWidth*Constants.BytesPerPixel; image.CopyPixels(new Int32Rect(0, line, stride, 1), bytes, stride, 0); return bytes; }
/// <summary> 把 BitmapSource 转换成指定起始点和宽高的 Bitmap </summary> /// <param name="bs"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public static Bitmap ConvertToBitmap(this BitmapSource bs, int x, int y, int width, int height) { var bmp = new Bitmap(width, height, PixelFormat.Format32bppPArgb); var bmpdata = bmp.LockBits(new Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, PixelFormat.Format32bppPArgb); bs.CopyPixels(new Int32Rect(x, y, width, height), bmpdata.Scan0, bmpdata.Height * bmpdata.Stride, bmpdata.Stride); bmp.UnlockBits(bmpdata); return bmp; }
// Copy Pixels from the bitmap source into a PixelColor array, i.e., flattens out those pixels into one huge array public static unsafe void CopyPixelsEx(this BitmapSource source, PixelColor[] pixels, int stride, int offset) { fixed (PixelColor* buffer = &pixels[0]) source.CopyPixels( new System.Windows.Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), (IntPtr)(buffer + offset), pixels.Length * sizeof(PixelColor), stride); }
public static unsafe void CopyPixels(this BitmapSource source, PixelColor[,] pixels, int stride, int offset) { fixed(PixelColor* buffer = &pixels[0, 0]) source.CopyPixels( new Int32Rect(0, 0, source.PixelWidth, source.PixelHeight), (IntPtr)(buffer + offset), pixels.GetLength(0) * pixels.GetLength(1) * sizeof(PixelColor), stride); }
/// <summary> /// 获取图像的指定区域的像素数组 /// </summary> /// <param name="目标矩形区域">目标矩形区域</param> /// <returns>目标矩形区域内的像素数组</returns> public static byte[] 获取像素数组(this BitmapSource b, Int32Rect 目标矩形区域) { //计算Stride var stride = b.Format.BitsPerPixel * 目标矩形区域.Width / 8; //声明字节数组 byte[] data = new byte[目标矩形区域.Height * stride]; //调用CopyPixels b.CopyPixels(目标矩形区域, data, stride, 0); return data; }
public static System.Drawing.Bitmap BitmapSourceToBitmap2(this System.Windows.Media.Imaging.BitmapSource srs) { System.Drawing.Bitmap btm = null; int width = srs.PixelWidth; int height = srs.PixelHeight; int stride = width * ((srs.Format.BitsPerPixel + 7) / 8); IntPtr ptr = Marshal.AllocHGlobal(height * stride); srs.CopyPixels(new Int32Rect(0, 0, width, height), ptr, height * stride, stride); btm = new System.Drawing.Bitmap(width, height, stride, System.Drawing.Imaging.PixelFormat.Format1bppIndexed, ptr); return btm; }
public static void CopyPixels(this BitmapSource source, ColorRGBA[,] pixels, int stride, int offset) { var height = source.PixelHeight; var width = source.PixelWidth; var pixelBytes = new byte[height * width * 4]; source.CopyPixels(pixelBytes, stride, 0); int y0 = offset / width; int x0 = offset - width * y0; for (int y = 0; y < height; y++) for (int x = 0; x < width; x++) pixels[x + x0, y + y0] = new ColorRGBA { Blue = pixelBytes[(y * width + x) * 4 + 0], Green = pixelBytes[(y * width + x) * 4 + 1], Red = pixelBytes[(y * width + x) * 4 + 2], Alpha = pixelBytes[(y * width + x) * 4 + 3], }; }
public static bool IsGrayscaleImage(this BitmapSource source) { if (source.Format != PixelFormats.Bgra32) { throw new InvalidOperationException("the source must be with Bgra32 pixel format"); } int len = (int)source.Width * (int)source.Height * 4; byte[] pixels = new byte[len]; source.CopyPixels(pixels, (int)source.Width * 4, 0); for (int i = 0; i < len; i = i + 4) { // if alpha is != 0 and not r == g == b if (pixels[i + 3] != 0 && ((pixels[i] != pixels[i + 1] || pixels[i + 1] != pixels[i + 2]))) { return false; } } return true; }
/// <remarks> /// Stolen and adapted from /// <seealso href="http://stackoverflow.com/questions/2284353/is-there-a-good-way-to-convert-between-bitmapsource-and-bitmap"> /// Is there a good way to convert between BitmapSource and Bitmap? /// </seealso> /// </remarks> internal static GdiPlus.Bitmap ConvertToGdiPlusBitmap (this Wpf.Media.Imaging.BitmapSource bitmapSource) { var bmp = new GdiPlus.Bitmap ( bitmapSource.PixelWidth, bitmapSource.PixelHeight, GdiPlus.Imaging.PixelFormat.Format32bppPArgb); var rectangle = new GdiPlus.Rectangle (GdiPlus.Point.Empty, bmp.Size); var data = bmp.LockBits ( rectangle, GdiPlus.Imaging.ImageLockMode.WriteOnly, GdiPlus.Imaging.PixelFormat.Format32bppPArgb ); bitmapSource.CopyPixels ( Wpf.Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride); bmp.UnlockBits (data); return bmp; }
public static byte[] GetBytes(this BitmapSource image) { byte[] bytes = new byte[image.PixelWidth*Constants.BytesPerPixel*image.PixelHeight]; image.CopyPixels(bytes, image.PixelWidth*Constants.BytesPerPixel, 0); return bytes; }
/// <summary> /// BitmapSourceをMatに変換する. /// </summary> /// <param name="src">変換するBitmapSource</param> /// <param name="dst">出力先のMat</param> #else /// <summary> /// Converts BitmapSource to Mat /// </summary> /// <param name="src">Input BitmapSource</param> /// <param name="dst">Output Mat</param> #endif public static void ToMat(this BitmapSource src, Mat dst) { if (src == null) throw new ArgumentNullException("src"); if (dst == null) throw new ArgumentNullException("dst"); if (src.PixelWidth != dst.Width || src.PixelHeight != dst.Height) throw new ArgumentException("size of src must be equal to size of dst"); if (dst.Dims() > 2) throw new ArgumentException("Mat dimensions must be 2"); int w = src.PixelWidth; int h = src.PixelHeight; int bpp = src.Format.BitsPerPixel; int channels = WriteableBitmapConverter.GetOptimumChannels(src.Format); if (dst.Channels() != channels) { throw new ArgumentException("nChannels of dst is invalid", "dst"); } bool submat = dst.IsSubmatrix(); bool continuous = dst.IsContinuous(); unsafe { byte* p = (byte*)(dst.Data); long step = dst.Step(); // 1bppは手作業でコピー if (bpp == 1) { if (submat) throw new NotImplementedException("submatrix not supported"); // BitmapImageのデータを配列にコピー // 要素1つに横8ピクセル分のデータが入っている。 int stride = (w / 8) + 1; byte[] pixels = new byte[h * stride]; src.CopyPixels(pixels, stride, 0); int x = 0; for (int y = 0; y < h; y++) { int offset = y * stride; // この行の各バイトを調べていく for (int bytePos = 0; bytePos < stride; bytePos++) { if (x < w) { // 現在の位置のバイトからそれぞれのビット8つを取り出す byte b = pixels[offset + bytePos]; for (int i = 0; i < 8; i++) { if (x >= w) { break; } p[step * y + x] = ((b & 0x80) == 0x80) ? (byte)255 : (byte)0; b <<= 1; x++; } } } // 次の行へ x = 0; } } // 8bpp /*else if (bpp == 8) { int stride = w; byte[] pixels = new byte[h * stride]; src.CopyPixels(pixels, stride, 0); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { p[step * y + x] = pixels[y * stride + x]; } } }*/ // 24bpp, 32bpp, ... else { int stride = w * ((bpp + 7) / 8); if (!submat && continuous) { long imageSize = dst.DataEnd.ToInt64() - dst.Data.ToInt64(); if (imageSize < 0) throw new OpenCvSharpException("The mat has invalid data pointer"); if (imageSize > Int32.MaxValue) throw new OpenCvSharpException("Too big mat data"); src.CopyPixels(Int32Rect.Empty, dst.Data, (int)imageSize, stride); } else { // 高さ1pxの矩形ごと(≒1行ごと)にコピー var roi = new Int32Rect { X = 0, Y = 0, Width = w, Height = 1 }; IntPtr dstData = dst.Data; for (int y = 0; y < h; y++) { roi.Y = y; src.CopyPixels(roi, dstData, stride, stride); dstData = new IntPtr(dstData.ToInt64() + stride); } } } } }
/// <summary> /// WriteableBitmapをMatに変換する. /// </summary> /// <param name="src">変換するWriteableBitmap</param> /// <param name="dst">出力先のMat</param> #else /// <summary> /// Converts WriteableBitmap to Mat /// </summary> /// <param name="src">Input WriteableBitmap</param> /// <param name="dst">Output Mat</param> #endif public static void ToMat(this WriteableBitmap src, Mat dst) { if (src == null) throw new ArgumentNullException("src"); if (dst == null) throw new ArgumentNullException("dst"); if (src.PixelWidth != dst.Width || src.PixelHeight != dst.Height) throw new ArgumentException("size of src must be equal to size of dst"); if (dst.Dims() > 2) throw new ArgumentException("Mat dimensions must be 2"); int w = src.PixelWidth; int h = src.PixelHeight; int bpp = src.Format.BitsPerPixel; int channels = GetOptimumChannels(src.Format); if (dst.Channels() != channels) { throw new ArgumentException("nChannels of dst is invalid", "dst"); } unsafe { byte* p = (byte*)(dst.Data); long step = dst.Step(); // 1bppは手作業でコピー if (bpp == 1) { // BitmapImageのデータを配列にコピー // 要素1つに横8ピクセル分のデータが入っている。 int stride = (w / 8) + 1; byte[] pixels = new byte[h * stride]; src.CopyPixels(pixels, stride, 0); int x = 0; for (int y = 0; y < h; y++) { int offset = y * stride; // この行の各バイトを調べていく for (int bytePos = 0; bytePos < stride; bytePos++) { if (x < w) { // 現在の位置のバイトからそれぞれのビット8つを取り出す byte b = pixels[offset + bytePos]; for (int i = 0; i < 8; i++) { if (x >= w) { break; } p[step * y + x] = ((b & 0x80) == 0x80) ? (byte)255 : (byte)0; b <<= 1; x++; } } } // 次の行へ x = 0; } } // 8bpp /*else if (bpp == 8) { int stride = w; byte[] pixels = new byte[h * stride]; src.CopyPixels(pixels, stride, 0); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { p[step * y + x] = pixels[y * stride + x]; } } }*/ // 24bpp, 32bpp, ... else { int stride = w * ((bpp + 7) / 8); long imageSize = dst.DataEnd.ToInt64() - dst.DataStart.ToInt64(); if (imageSize < 0) throw new OpenCvSharpException("The mat has invalid data pointer"); if (imageSize > Int32.MaxValue) throw new OpenCvSharpException("Too big mat data"); src.CopyPixels(Int32Rect.Empty, dst.Data, (int)imageSize, stride); } } }
/// <summary> /// WriteableBitmapをIplImageに変換する. /// </summary> /// <param name="src">変換するWriteableBitmap</param> /// <param name="dst">出力先のIplImage</param> #else /// <summary> /// Converts WriteableBitmap to IplImage /// </summary> /// <param name="src">Input WriteableBitmap</param> /// <param name="dst">Output IplImage</param> #endif public static void ToIplImage(this WriteableBitmap src, IplImage dst) { if (src == null) throw new ArgumentNullException("src"); if (dst == null) throw new ArgumentNullException("dst"); if (src.PixelWidth != dst.Width || src.PixelHeight != dst.Height) throw new ArgumentException("size of src must be equal to size of dst"); //if (dst.Depth != BitDepth.U8) // throw new ArgumentException("bit depth of dst must be BitDepth.U8", "dst"); int w = src.PixelWidth; int h = src.PixelHeight; int bpp = src.Format.BitsPerPixel; int channels = GetOptimumChannels(src.Format); if (dst.NChannels != channels) { throw new ArgumentException("nChannels of dst is invalid", "dst"); } unsafe { byte* p = (byte*)(dst.ImageData.ToPointer()); int widthStep = dst.WidthStep; // 1bppは手作業でコピー if (bpp == 1) { // BitmapImageのデータを配列にコピー // 要素1つに横8ピクセル分のデータが入っている。 int stride = (w / 8) + 1; byte[] pixels = new byte[h * stride]; src.CopyPixels(pixels, stride, 0); int offset = 0; int x = 0; int y; int byte_pos; int i; byte b; for (y = 0; y < h; y++) { offset = y * stride; // この行の各バイトを調べていく for (byte_pos = 0; byte_pos < stride; byte_pos++) { if (x < w) { // 現在の位置のバイトからそれぞれのビット8つを取り出す b = pixels[offset + byte_pos]; for (i = 0; i < 8; i++) { if (x >= w) { break; } // IplImageは8bit/pixel p[widthStep * y + x] = ((b & 0x80) == 0x80) ? (byte)255 : (byte)0; b <<= 1; x++; } } } // 次の行へ x = 0; } } // 8bpp else if (bpp == 8) { int stride = w; byte[] pixels = new byte[h * stride]; src.CopyPixels(pixels, stride, 0); for (int y = 0; y < h; y++) { for (int x = 0; x < w; x++) { p[widthStep * y + x] = pixels[y * stride + x]; } } } // 24bpp, 32bpp, ... else { int stride = w * ((bpp + 7) / 8); src.CopyPixels(Int32Rect.Empty, dst.ImageData, dst.ImageSize, stride); } } }
/// <summary> 把 BitmapSource 转换成指定起始点和宽高的 byte[] </summary> /// <param name="bs"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="width"></param> /// <param name="height"></param> /// <returns></returns> public static byte[] ConvertToBytes(this BitmapSource bs, int x, int y, int width, int height) { var rect = new Int32Rect(x, y, width, height); var stride = bs.Format.BitsPerPixel * rect.Width / 8; byte[] data = new byte[rect.Height * stride]; bs.CopyPixels(rect, data, stride, 0); return data; }
public static Color GetColor(this BitmapSource image, int x, int y) { byte[] colorBytes = new byte[Constants.BytesPerPixel]; image.CopyPixels(new Int32Rect(x, y, 1, 1), colorBytes, image.PixelWidth*Constants.BytesPerPixel, 0); return Color.FromArgb(colorBytes[3], colorBytes[2], colorBytes[1], colorBytes[0]); }
public static System.Drawing.Bitmap GetBitmap(this BitmapSource source) { Bitmap bmp = new Bitmap( source.PixelWidth, source.PixelHeight, System.Drawing.Imaging.PixelFormat.Format32bppArgb); BitmapData data = bmp.LockBits( new Rectangle(System.Drawing.Point.Empty, bmp.Size), ImageLockMode.WriteOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); source.CopyPixels( Int32Rect.Empty, data.Scan0, data.Height * data.Stride, data.Stride); bmp.UnlockBits(data); return bmp; }
public static WriteableBitmap ResizeWritableBitmap(this WriteableBitmap wBitmap, int reqWidth, int reqHeight) { int Stride = wBitmap.PixelWidth * ((wBitmap.Format.BitsPerPixel + 7) / 8); int NumPixels = Stride * wBitmap.PixelHeight; ushort[] ArrayOfPixels = new ushort[NumPixels]; wBitmap.CopyPixels(ArrayOfPixels, Stride, 0); int OriWidth = (int)wBitmap.PixelWidth; int OriHeight = (int)wBitmap.PixelHeight; double nXFactor = (double)OriWidth / (double)reqWidth; double nYFactor = (double)OriHeight / (double)reqHeight; double fraction_x, fraction_y, one_minus_x, one_minus_y; int ceil_x, ceil_y, floor_x, floor_y; ushort pix1, pix2, pix3, pix4; int nStride = reqWidth * ((wBitmap.Format.BitsPerPixel + 7) / 8); int nNumPixels = reqWidth * reqHeight; ushort[] newArrayOfPixels = new ushort[nNumPixels]; /*Core Part*/ /* Code project article : Image Processing for Dummies with C# and GDI+ Part 2 - Convolution Filters By Christian Graus</a> href=<a href="http://www.codeproject.com/KB/GDI-plus/csharpfilters.aspx"></a> */ for (int y = 0; y < reqHeight; y++) { for (int x = 0; x < reqWidth; x++) { // Setup floor_x = (int)Math.Floor(x * nXFactor); floor_y = (int)Math.Floor(y * nYFactor); ceil_x = floor_x + 1; if (ceil_x >= OriWidth) ceil_x = floor_x; ceil_y = floor_y + 1; if (ceil_y >= OriHeight) ceil_y = floor_y; fraction_x = x * nXFactor - floor_x; fraction_y = y * nYFactor - floor_y; one_minus_x = 1.0 - fraction_x; one_minus_y = 1.0 - fraction_y; pix1 = ArrayOfPixels[floor_x + floor_y * OriWidth]; pix2 = ArrayOfPixels[ceil_x + floor_y * OriWidth]; pix3 = ArrayOfPixels[floor_x + ceil_y * OriWidth]; pix4 = ArrayOfPixels[ceil_x + ceil_y * OriWidth]; ushort g1 = (ushort)(one_minus_x * pix1 + fraction_x * pix2); ushort g2 = (ushort)(one_minus_x * pix3 + fraction_x * pix4); ushort g = (ushort)(one_minus_y * (double)(g1) + fraction_y * (double)(g2)); newArrayOfPixels[y * reqWidth + x] = g; } } /*End of Core Part*/ WriteableBitmap newWBitmap = new WriteableBitmap(reqWidth, reqHeight, 96, 96, PixelFormats.Gray16, null); Int32Rect Imagerect = new Int32Rect(0, 0, reqWidth, reqHeight); int newStride = reqWidth * ((PixelFormats.Gray16.BitsPerPixel + 7) / 8); newWBitmap.WritePixels(Imagerect, newArrayOfPixels, newStride, 0); return newWBitmap; }