Пример #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);
        }
Пример #2
0
            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;
             * }*/

            public static byte[] CreatePackedDIBV5(Bitmap image)
            {
                BitmapData bmData;

                using (Bitmap bm32b = new Bitmap(image.Width, image.Height, PixelFormat.Format32bppArgb)) {
                    using (Graphics g = Graphics.FromImage(bm32b))
                        g.DrawImage(image, new Rectangle(0, 0, bm32b.Width, bm32b.Height));
                    // Bitmap format has its lines reversed.
                    bm32b.RotateFlip(RotateFlipType.Rotate180FlipX);
                    bmData = image.LockBits(new Rectangle(0, 0, image.Width, image.Height),
                                            ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
                }
                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 = new BITMAPV5HEADER();                // (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   = 0;              // BI_BITFIELDS;
                bmi.bV5XPelsPerMeter = 0;
                bmi.bV5YPelsPerMeter = 0;
                bmi.bV5ClrUsed       = 0;
                bmi.bV5ClrImportant  = 0;
                bmi.bV5RedMask       = 0x000000FF;
                bmi.bV5GreenMask     = 0x0000FF00;
                bmi.bV5BlueMask      = 0x00FF0000;
                bmi.bV5AlphaMask     = 0xFF000000;
                bmi.bV5CSType        = 0x206E6957;         // LCS_WINDOWS_COLOR_SPACE;
                bmi.bV5GammaBlue     = 0;
                bmi.bV5GammaGreen    = 0;
                bmi.bV5GammaRed      = 0;
                bmi.bV5ProfileData   = 0;
                bmi.bV5ProfileSize   = 0;
                bmi.bV5Reserved      = 0;
                bmi.bV5Intent        = 0;         // 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 = new BITFIELDS();                // (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);

                //byte[] dibData = new byte[bufferLen];
                byte[] imageData = new byte[bmi.bV5SizeImage];

                using (MemoryStream ms = new MemoryStream()) {
                    var writer = new BinaryWriter(ms);
                    writer.WriteStruct(bmi);
                    //writer.WriteStruct(Masks);
                    Marshal.Copy(bmData.Scan0, imageData, 0, imageData.Length);
                    writer.Write(imageData);
                    return(ms.ToArray());
                }

                /*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.CreateDIBitmap(hdc, handle.AddrOfPinnedObject(), CBM_INIT,
                 *                                                                        bits, handle.AddrOfPinnedObject(), (uint) DIB.DIB_RGB_COLORS);
                 * bm.UnlockBits(bmData);
                 *
                 * GlobalUnlock(hMem);
                 *
                 *
                 * return hBitmap;*/
            }