private static unsafe void FillBitmapInfo(ref Win32API.BITMAPINFO bmi, int width, int height, int bpp, int origin) { Debug.Assert(width > 0 && height > 0 && (bpp == 8 || bpp == 24 || bpp == 32)); Win32API.BITMAPINFOHEADER bmih = bmi.Header; using (ScopedGCHandle handle = new ScopedGCHandle(bmih, GCHandleType.Pinned)) { //Win32API.FillMemory(handle.AddrOfPinnedObject(), Marshal.SizeOf(typeof(Win32API.BITMAPINFOHEADER)), 0); bmih.Size = (uint)sizeof(Win32API.BITMAPINFOHEADER); bmih.Width = width; bmih.Height = (origin != 0) ? Math.Abs(height) : -Math.Abs(height); bmih.Planes = 1; bmih.BitCount = (ushort)bpp; bmih.Compression = Win32API.BI_RGB; bmih.ClrImportant = 0; bmih.Compression = 0; bmih.SizeImage = 0; bmih.XPelsPerMeter = 0; bmih.YPelsPerMeter = 0; bmi.Header = bmih; } if (bpp == 8) { Win32API.RGBQUAD[] palette = bmi.Colors; for (int i = 0; i < palette.Length; i++) { palette[i].Blue = palette[i].Green = palette[i].Red = (byte)i; palette[i].Reserved = 0; } bmi.Colors = palette; } }
/// <summary> /// /// </summary> /// <param name="img"></param> /// <param name="hdc"></param> /// <param name="dstRect"></param> public static void DrawToHdc(this IplImage img, IntPtr hdc, CvRect dstRect) { if (Platform.OS == OS.Unix) { throw new PlatformNotSupportedException("This method is only for Windows."); } if (img == null) { throw new ArgumentNullException("img"); } if (hdc == IntPtr.Zero) { throw new ArgumentNullException("hdc"); } if (img.Depth != BitDepth.U8) { throw new NotSupportedException(); } int bmpW = img.Width; int bmpH = img.Height; CvRect roi = Cv.GetImageROI(img); unsafe { int headerSize = sizeof(Win32API.BITMAPINFOHEADER) + 1024; IntPtr buffer = Marshal.AllocHGlobal(headerSize); Win32API.BITMAPINFO bmi = (Win32API.BITMAPINFO)Marshal.PtrToStructure(buffer, typeof(Win32API.BITMAPINFO)); if (roi.Width == dstRect.Width && roi.Height == dstRect.Height) { DrawToHdc(img, hdc, dstRect.X, dstRect.Y, dstRect.Width, dstRect.Height, roi.X, roi.Y); return; } if (roi.Width > dstRect.Width) { Win32API.SetStretchBltMode(hdc, Win32API.HALFTONE); } else { Win32API.SetStretchBltMode(hdc, Win32API.COLORONCOLOR); } FillBitmapInfo(ref bmi, bmpW, bmpH, img.Bpp, (int)img.Origin); Win32API.StretchDIBits( hdc, dstRect.X, dstRect.Y, dstRect.Width, dstRect.Height, roi.X, roi.Y, roi.Width, roi.Height, img.ImageData, ref bmi, Win32API.DIB_RGB_COLORS, Win32API.SRCCOPY); Marshal.FreeHGlobal(buffer); } }
/// <summary> /// /// </summary> /// <param name="img"></param> /// <param name="hdc"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="w"></param> /// <param name="h"></param> /// <param name="fromX"></param> /// <param name="fromY"></param> public static void DrawToHdc(this IplImage img, IntPtr hdc, int x, int y, int w, int h, int fromX, int fromY) { if (Platform.OS == OS.Unix) { throw new PlatformNotSupportedException("This method is only for Windows."); } if (img == null) { throw new ArgumentNullException("img"); } if (hdc == IntPtr.Zero) { throw new ArgumentNullException("hdc"); } if (img.Depth != BitDepth.U8) { throw new NotSupportedException(); } int bmpW = img.Width; int bmpH = img.Height; unsafe { int headerSize = sizeof(Win32API.BITMAPINFOHEADER) + 1024; IntPtr buffer = Marshal.AllocHGlobal(headerSize); Win32API.BITMAPINFO bmi = (Win32API.BITMAPINFO)Marshal.PtrToStructure(buffer, typeof(Win32API.BITMAPINFO)); FillBitmapInfo(ref bmi, bmpW, bmpH, img.Bpp, (int)img.Origin); fromX = Math.Min(Math.Max(fromX, 0), bmpW - 1); fromY = Math.Min(Math.Max(fromY, 0), bmpH - 1); uint sw = (uint)Math.Max(Math.Min(bmpW - fromX, w), 0); uint sh = (uint)Math.Max(Math.Min(bmpH - fromY, h), 0); Win32API.SetDIBitsToDevice( hdc, x, y, sw, sh, fromX, fromY, (uint)fromY, sh, new IntPtr(img.ImageData.ToInt32() + fromY * img.WidthStep), ref bmi, Win32API.DIB_RGB_COLORS); Marshal.FreeHGlobal(buffer); } }