const int CBM_INIT = 0x04;// /* initialize bitmap */ public static IntPtr Create32BppBitmap(Image sourceImage) { BITMAPV5HEADER bi = new BITMAPV5HEADER(); bi.bV5Size = (uint)Marshal.SizeOf(bi); bi.bV5Width = sourceImage.Width; bi.bV5Height = sourceImage.Height; bi.bV5Planes = 1; bi.bV5BitCount = 32; bi.bV5Compression = BI_BITFIELDS; // The following mask specification specifies a supported 32 BPP // alpha format for Windows XP. bi.bV5RedMask = 0x00FF0000; bi.bV5GreenMask = 0x0000FF00; bi.bV5BlueMask = 0x000000FF; bi.bV5AlphaMask = 0xFF000000; IntPtr hdc = User32.GetDC(IntPtr.Zero); IntPtr bits = IntPtr.Zero; // Create the DIB section with an alpha channel. IntPtr hBitmap = Gdi32.CreateDIBSection(hdc, bi, (uint)DIB.DIB_RGB_COLORS, out bits, IntPtr.Zero, 0); var hMemDC = Gdi32.CreateCompatibleDC(hdc); Gdi32.ReleaseDC(IntPtr.Zero, hdc); var sourceBits = ((Bitmap) sourceImage).LockBits( new Rectangle(0, 0, sourceImage.Width, sourceImage.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); var stride = sourceImage.Width*4; for (int y = 0; y < sourceImage.Height; y++) { IntPtr DstDib = (IntPtr)(bits.ToInt32() + (y * stride)); IntPtr SrcDib = (IntPtr)(sourceBits.Scan0.ToInt32() + ((sourceImage.Height - 1 - y) * stride)); for (int x = 0; x < sourceImage.Width; x++) { Marshal.WriteInt32(DstDib, Marshal.ReadInt32(SrcDib)); DstDib = (IntPtr)(DstDib.ToInt32() + 4); SrcDib = (IntPtr)(SrcDib.ToInt32() + 4); } } return hBitmap; }
internal static extern IntPtr CreateDIBSection(IntPtr hdc, [In] BITMAPV5HEADER pbmi, uint pila, out IntPtr ppvBits, IntPtr hSection, uint dwOffset);