Ejemplo n.º 1
0
        public static IntPtr CreatePackedDIBV5(Bitmap bm)
        {
            BitmapData bmData = bm.LockBits(new Rectangle(0, 0, bm.Width, bm.Height),
                                            ImageLockMode.ReadOnly, bm.PixelFormat);
            uint bufferLen = (uint)(Marshal.SizeOf(typeof(BITMAPV5HEADER)) +
                                    (Marshal.SizeOf(typeof(uint)) * 3) + bmData.Height * bmData.Stride);
            IntPtr         hMem        = GlobalAlloc(GHND | GMEM_DDESHARE, bufferLen);
            IntPtr         packedDIBV5 = GlobalLock(hMem);
            BITMAPV5HEADER bmi         = (BITMAPV5HEADER)Marshal.PtrToStructure(packedDIBV5,
                                                                                typeof(BITMAPV5HEADER));

            bmi.bV5Size          = (uint)Marshal.SizeOf(typeof(BITMAPV5HEADER));
            bmi.bV5Width         = bmData.Width;
            bmi.bV5Height        = bmData.Height;
            bmi.bV5BitCount      = 32;
            bmi.bV5Planes        = 1;
            bmi.bV5Compression   = BI_BITFIELDS;
            bmi.bV5XPelsPerMeter = 0;
            bmi.bV5YPelsPerMeter = 0;
            bmi.bV5ClrUsed       = 0;
            bmi.bV5ClrImportant  = 0;
            bmi.bV5BlueMask      = 0x000000FF;
            bmi.bV5GreenMask     = 0x0000FF00;
            bmi.bV5RedMask       = 0x00FF0000;
            bmi.bV5AlphaMask     = 0xFF000000;
            bmi.bV5CSType        = LCS_WINDOWS_COLOR_SPACE;
            bmi.bV5GammaBlue     = 0;
            bmi.bV5GammaGreen    = 0;
            bmi.bV5GammaRed      = 0;
            bmi.bV5ProfileData   = 0;
            bmi.bV5ProfileSize   = 0;
            bmi.bV5Reserved      = 0;
            bmi.bV5Intent        = LCS_GM_IMAGES;
            bmi.bV5SizeImage     = (uint)(bmData.Height * bmData.Stride);
            bmi.bV5Endpoints.ciexyzBlue.ciexyzX          =
                bmi.bV5Endpoints.ciexyzBlue.ciexyzY      =
                    bmi.bV5Endpoints.ciexyzBlue.ciexyzZ  = 0;
            bmi.bV5Endpoints.ciexyzGreen.ciexyzX         =
                bmi.bV5Endpoints.ciexyzGreen.ciexyzY     =
                    bmi.bV5Endpoints.ciexyzGreen.ciexyzZ = 0;
            bmi.bV5Endpoints.ciexyzRed.ciexyzX           =
                bmi.bV5Endpoints.ciexyzRed.ciexyzY       =
                    bmi.bV5Endpoints.ciexyzRed.ciexyzZ   = 0;
            Marshal.StructureToPtr(bmi, packedDIBV5, false);

            BITFIELDS Masks = (BITFIELDS)Marshal.PtrToStructure(
                (IntPtr)(packedDIBV5.ToInt32() + bmi.bV5Size), typeof(BITFIELDS));

            Masks.BlueMask  = 0x000000FF;
            Masks.GreenMask = 0x0000FF00;
            Masks.RedMask   = 0x00FF0000;
            Marshal.StructureToPtr(Masks, (IntPtr)(packedDIBV5.ToInt32() +
                                                   bmi.bV5Size), false);

            long   offsetBits = bmi.bV5Size + Marshal.SizeOf(typeof(uint)) * 3;
            IntPtr bits       = (IntPtr)(packedDIBV5.ToInt32() + offsetBits);


            for (int y = 0; y < bmData.Height; y++)
            {
                IntPtr DstDib = (IntPtr)(bits.ToInt32() + (y * bmData.Stride));
                IntPtr SrcDib = (IntPtr)(bmData.Scan0.ToInt32() + ((bmData.Height - 1 - y) *
                                                                   bmData.Stride));

                for (int x = 0; x < bmData.Width; x++)
                {
                    Marshal.WriteInt32(DstDib, Marshal.ReadInt32(SrcDib));
                    DstDib = (IntPtr)(DstDib.ToInt32() + 4);
                    SrcDib = (IntPtr)(SrcDib.ToInt32() + 4);
                }
            }

            // Create the DIB section with an alpha channel.
            IntPtr hdc = User32.GetDC(IntPtr.Zero);
            //IntPtr hdc = Gdi32.CreateCompatibleDC(IntPtr.Zero);
            GCHandle handle = GCHandle.Alloc(bmi, GCHandleType.Pinned);

            /*IntPtr hBitmap = Gdi32.CreateDIBSection(hdc, handle.AddrOfPinnedObject(), (uint)SharpThumbnailHandler.DIB.DIB_RGB_COLORS,
             *  out bits, IntPtr.Zero, 0);*/
            IntPtr hBitmap = Gdi32.CreateDIBitmap(hdc, handle.AddrOfPinnedObject(), CBM_INIT,
                                                  bits, handle.AddrOfPinnedObject(), (uint)DIB.DIB_RGB_COLORS);

            bm.UnlockBits(bmData);

            GlobalUnlock(hMem);


            return(hBitmap);
        }