123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249 |
- using AI.Common;
- using System;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.IO;
- using System.Runtime.InteropServices;
- using System.Windows.Media.Imaging;
- using Rectangle = System.Drawing.Rectangle;
- namespace AIDiagnosisDemo.Infrastucture
- {
- internal class BitmapHelper
- {
- public static byte[] BitmapToBytes(Bitmap bitmap)
- {
- if (bitmap == null)
- {
- return null;
- }
- using (var stream = new MemoryStream())
- {
- bitmap.Save(stream, ImageFormat.Bmp);
- var buffer = new byte[stream.Length];
- stream.Position = 0;
- stream.Read(buffer, 0, buffer.Length);
- return buffer;
- }
- }
- public static BitmapImage BitmapToBitmapImage(Bitmap bitmap)
- {
- BitmapImage bmpimg = new BitmapImage();
- using (MemoryStream ms = new MemoryStream())
- {
- bitmap.Save(ms, ImageFormat.Png);
- bmpimg.BeginInit();
- bmpimg.StreamSource = ms;
- bmpimg.CacheOption = BitmapCacheOption.OnLoad;
- bmpimg.EndInit();
- bmpimg.Freeze();
- ms.Dispose();
- }
- return bmpimg;
- }
- public static RawImage BitmapToRawImage(Bitmap image, bool keepColorType = false)
- {
- int width = image.Width;
- int height = image.Height;
- PixelFormat pixelFormat = image.PixelFormat;
- if (pixelFormat != PixelFormat.Format24bppRgb && pixelFormat != PixelFormat.Format32bppArgb
- && pixelFormat != PixelFormat.Format8bppIndexed && pixelFormat != PixelFormat.Format16bppGrayScale)
- {
- throw new Exception("Unexpected image pixel format:" + pixelFormat);
- }
- EnumColorType origColorType = EnumColorType.Gray8;
- int origBytesPerPixel = 1;
- if (pixelFormat == PixelFormat.Format8bppIndexed)
- {
- origColorType = EnumColorType.Gray8;
- origBytesPerPixel = 1;
- }
- else if (pixelFormat == PixelFormat.Format16bppGrayScale)
- {
- origColorType = EnumColorType.Gray16;
- origBytesPerPixel = 2;
- }
- else if (pixelFormat == PixelFormat.Format24bppRgb)
- {
- // 注意Bitmap里的24bppRgb其实通道顺序是BGR
- origColorType = EnumColorType.Bgr;
- origBytesPerPixel = 3;
- }
- else
- {
- // 注意Bitmap里的32Argb其实通道顺序是Bgra
- origColorType = EnumColorType.Bgra;
- origBytesPerPixel = 4;
- }
- EnumColorType dstColorType;
- int dstBytesPerPixel;
- if (keepColorType)
- {
- dstColorType = origColorType;
- dstBytesPerPixel = origBytesPerPixel;
- }
- else
- {
- // 如果没有指定要keepColorType的话,默认都转成BGR
- dstColorType = EnumColorType.Bgr;
- dstBytesPerPixel = 3;
- }
- var bmData = image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, pixelFormat);
- byte[] dstDataArray = new byte[width * height * dstBytesPerPixel];
- unsafe
- {
- int stride = bmData.Stride;
- int dstStride = width * dstBytesPerPixel;
- IntPtr ptr = bmData.Scan0;
- IntPtr ptrH, ptrW;
- // 原图和目标图的ColorType相同
- if (origColorType == dstColorType)
- {
- for (int nh = 0; nh < height; nh++)
- {
- ptrH = IntPtr.Add(ptr, nh * stride);
- Marshal.Copy(ptrH, dstDataArray, nh * dstStride, dstStride);
- }
- }
- // 原图和目标图的ColorType不同
- else
- {
- // 如果原图是8位灰度图
- if (origColorType == EnumColorType.Gray8)
- {
- if (dstColorType == EnumColorType.Gray16)
- {
- byte gray;
- int dstOffset;
- for (int nh = 0; nh < height; nh++)
- {
- ptrH = IntPtr.Add(ptr, nh * stride);
- for (int nw = 0; nw < width; nw++)
- {
- ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
- gray = Marshal.ReadByte(ptrW);
- dstOffset = nh * dstStride + nw * dstBytesPerPixel;
- dstDataArray[dstOffset] = gray;
- // 高位为0,因此不用赋值
- }
- }
- }
- else
- {
- byte gray;
- int dstOffset;
- for (int nh = 0; nh < height; nh++)
- {
- ptrH = IntPtr.Add(ptr, nh * stride);
- for (int nw = 0; nw < width; nw++)
- {
- ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
- gray = Marshal.ReadByte(ptrW);
- dstOffset = nh * dstStride + nw * dstBytesPerPixel;
- dstDataArray[dstOffset] = gray;
- dstDataArray[dstOffset + 1] = gray;
- dstDataArray[dstOffset + 2] = gray;
- }
- }
- if (dstColorType == EnumColorType.Bgra)
- {
- for (int nh = 0; nh < height; nh++)
- {
- for (int nw = 0; nw < width; nw++)
- {
- dstOffset = nh * dstStride + nw * dstBytesPerPixel;
- dstDataArray[dstOffset + 3] = 255;
- }
- }
- }
- }
- }
- // 如果原图是BGR彩色图
- if (origColorType == EnumColorType.Bgr)
- {
- if (dstColorType == EnumColorType.Gray8 || dstColorType == EnumColorType.Gray16)
- {
- byte red, green, blue, gray;
- int dstOffset;
- for (int nh = 0; nh < height; nh++)
- {
- ptrH = IntPtr.Add(ptr, nh * stride);
- for (int nw = 0; nw < width; nw++)
- {
- ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
- blue = Marshal.ReadByte(ptrW);
- ptrW = IntPtr.Add(ptrW, 1);
- green = Marshal.ReadByte(ptrW);
- ptrW = IntPtr.Add(ptrW, 1);
- red = Marshal.ReadByte(ptrW);
- gray = RawImage.PixelRGBToGray(red, green, blue);
- dstOffset = nh * dstStride + nw * dstBytesPerPixel;
- dstDataArray[dstOffset] = gray;
- }
- }
- }
- if (dstColorType == EnumColorType.Bgra)
- {
- int dstOffset;
- for (int nh = 0; nh < height; nh++)
- {
- ptrH = IntPtr.Add(ptr, nh * stride);
- for (int nw = 0; nw < width; nw++)
- {
- ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
- dstOffset = nh * dstStride + nw * dstBytesPerPixel;
- Marshal.Copy(ptrW, dstDataArray, dstOffset, 3);
- dstDataArray[dstOffset + 3] = 255;
- }
- }
- }
- }
- // 如果原图是BGRA彩色图
- if (origColorType == EnumColorType.Bgra)
- {
- if (dstColorType == EnumColorType.Gray8 || dstColorType == EnumColorType.Gray16)
- {
- byte red, green, blue, gray;
- int dstOffset;
- for (int nh = 0; nh < height; nh++)
- {
- ptrH = IntPtr.Add(ptr, nh * stride);
- for (int nw = 0; nw < width; nw++)
- {
- ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
- blue = Marshal.ReadByte(ptrW);
- ptrW = IntPtr.Add(ptrW, 1);
- green = Marshal.ReadByte(ptrW);
- ptrW = IntPtr.Add(ptrW, 1);
- red = Marshal.ReadByte(ptrW);
- gray = RawImage.PixelRGBToGray(red, green, blue);
- dstOffset = nh * dstStride + nw * dstBytesPerPixel;
- dstDataArray[dstOffset] = gray;
- }
- }
- }
- if (dstColorType == EnumColorType.Bgr)
- {
- int dstOffset;
- for (int nh = 0; nh < height; nh++)
- {
- ptrH = IntPtr.Add(ptr, nh * stride);
- for (int nw = 0; nw < width; nw++)
- {
- ptrW = IntPtr.Add(ptrH, nw * origBytesPerPixel);
- dstOffset = nh * dstStride + nw * dstBytesPerPixel;
- Marshal.Copy(ptrW, dstDataArray, dstOffset, 3);
- }
- }
- }
- }
- }
- }
- image.UnlockBits(bmData);
- return new RawImage(dstDataArray, width, height, dstColorType);
- }
- }
- }
|