Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Bitmap bmp = new Bitmap(width, height, PixelFormat.Format8bppIndexed)
- BitmapData bmpData = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, bmp.PixelFormat);
- // Write my data into bmpData.Scan0
- bmp.UnlockBits(bmpData);
- const int XPelsPerMeter = 0xb12; // 72 ppi, 96 would work well too
- const int YPelsPerMeter = 0xb12;
- const int Gptr = 0x40;
- const int Srccopy = 0x00CC0020;
- struct BITMAPFILEHEADER
- {
- public ushort bfType;
- public uint bfSize;
- public ushort bfReserved1;
- public ushort bfReserved2;
- public uint bfOffBits;
- }
- struct BITMAPINFOHEADER
- {
- public uint biSize;
- public int biWidth;
- public int biHeight;
- public ushort biPlanes;
- public ushort biBitCount;
- public uint biCompression;
- public uint biSizeImage;
- public int biXPelsPerMeter;
- public int biYPelsPerMeter;
- public uint biClrUsed;
- public uint biClrImportant;
- }
- public static byte[] GetByteArray(Bitmap bitmap)
- {
- IntPtr hbm = bitmap.GetHbitmap(); // this is step (1)
- IntPtr sdc = GetDC( IntPtr.Zero ); // First we obtain the DC for the screen
- // Next, create a DC for the original hbitmap
- IntPtr hdc = CreateCompatibleDC( sdc );
- SelectObject( hdc, hbm );
- byte[] arrayBytes = CreateBinary(hdc, bitmap.Height, bitmap.Width);
- // Finally some cleanup.
- DeleteDC( hdc );
- ReleaseDC( IntPtr.Zero, sdc );
- DeleteObject( hbm );
- return arrayBytes;
- }
- static int WIDTHBYTES( int bits )
- {
- return ( ( ( ( bits ) + 31 ) / 32 ) * 4 );
- }
- private static byte[] CreateBinary( IntPtr hDc, int height, int width )
- {
- IntPtr hMemDc = CreateCompatibleDC( hDc );
- int cb = 0;
- BITMAPINFOHEADER bi = new BITMAPINFOHEADER();
- bi.biSize = ( uint )Marshal.SizeOf( bi );
- bi.biBitCount = 1; // Creating RGB bitmap. The following three members don't matter
- bi.biClrUsed = 2;
- bi.biClrImportant = 2;
- bi.biCompression = 0;
- bi.biHeight = height;
- bi.biWidth = width;
- bi.biPlanes = 1;
- cb = WIDTHBYTES( bi.biWidth * bi.biBitCount ) * bi.biHeight;
- bi.biSizeImage = ( uint )cb;
- bi.biXPelsPerMeter = XPelsPerMeter;
- bi.biYPelsPerMeter = YPelsPerMeter;
- IntPtr pBits = IntPtr.Zero;
- //Allocate memory for bitmap bits
- IntPtr pBi = LocalAlloc( Gptr, bi.biSize );
- // Not sure if this needed - simply trying to keep marshaller happy
- Marshal.StructureToPtr( bi, pBi, false );
- //This will return IntPtr to actual DIB bits in pBits
- IntPtr hBmp = CreateDIBSection( hDc, pBi, 0, ref pBits, IntPtr.Zero, 0 );
- //Marshall back - now we have BITMAPINFOHEADER correctly filled in
- //Marshal.PtrToStructure(pBI, bi);
- BITMAPINFOHEADER biNew = ( BITMAPINFOHEADER )Marshal.PtrToStructure( pBi, typeof( BITMAPINFOHEADER ) );
- //Usual stuff
- IntPtr hOldBitmap = SelectObject( hMemDc, hBmp );
- //Grab bitmap
- BitBlt( hMemDc, 0, 0, bi.biWidth, bi.biHeight, hDc, 0, 0, Srccopy );
- // Allocate memory for a copy of bitmap bits
- byte[] RealBits = new byte[cb];
- // And grab bits from DIBSestion data
- Marshal.Copy( pBits, RealBits, 0, cb );
- // This simply creates valid bitmap file header, so it can be saved to disk
- BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
- uint colorSize = 2 * 4;//2 colors for B&W, 4 bytes (RGBQUAD)
- uint sizeofBinfo = 0x36 + colorSize;//original
- //sizeofBINFO = (uint)Marshal.SizeOf(bi);//sorin
- //bfh.bfSize = ( uint )cb + 0x36; // Size of header + size of BITMAPINFOHEADER size of bitmap bits
- bfh.bfSize = ( uint )( cb + sizeofBinfo );
- bfh.bfType = 0x4d42; //BM
- bfh.bfOffBits = sizeofBinfo; //
- int HdrSize = 14;
- byte[] header = new byte[HdrSize];
- BitConverter.GetBytes( bfh.bfType ).CopyTo( header, 0 );
- BitConverter.GetBytes( bfh.bfSize ).CopyTo( header, 2 );
- BitConverter.GetBytes( bfh.bfOffBits ).CopyTo( header, 10 );
- //Allocate enough memory for complete bitmap file
- byte[] data = new byte[cb + bfh.bfOffBits];
- //BITMAPFILEHEADER
- header.CopyTo( data, 0 );
- //BITMAPINFOHEADER
- header = new byte[Marshal.SizeOf( bi )];
- IntPtr pHeader = LocalAlloc( Gptr, ( uint )Marshal.SizeOf( bi ) );
- Marshal.StructureToPtr( biNew, pHeader, false );
- Marshal.Copy( pHeader, header, 0, Marshal.SizeOf( bi ) );
- LocalFree( pHeader );
- header.CopyTo( data, HdrSize );
- //set black color as second color from color table
- byte[] colors = new byte[10];
- colors[4] = 255;
- colors[5] = 255;
- colors[6] = 255;
- colors.CopyTo( data, ( int )bfh.bfOffBits - ( int )colorSize );
- //Bitmap bits
- RealBits.CopyTo( data, ( int )bfh.bfOffBits );
- DeleteObject( SelectObject( hMemDc, hOldBitmap ) );
- DeleteDC( hMemDc );
- return data;
- }
- [DllImport( "coredll.dll" )]
- public static extern bool DeleteObject( IntPtr hObject );
- [DllImport( "coredll.dll" )]
- public static extern int InvalidateRect( IntPtr hwnd, IntPtr rect, int bErase );
- [DllImport( "coredll.dll" )]
- public static extern IntPtr GetDC( IntPtr hwnd );
- [DllImport( "coredll.dll" )]
- public static extern IntPtr CreateCompatibleDC( IntPtr hdc );
- [DllImport( "coredll.dll" )]
- public static extern int ReleaseDC( IntPtr hwnd, IntPtr hdc );
- [DllImport( "coredll.dll" )]
- public static extern int DeleteDC( IntPtr hdc );
- [DllImport( "coredll.dll" )]
- public static extern IntPtr SelectObject( IntPtr hdc, IntPtr hgdiobj );
- [DllImport( "coredll.dll" )]
- public static extern int BitBlt( IntPtr hdcDst, int xDst, int yDst, int w, int h, IntPtr hdcSrc, int xSrc, int ySrc, int rop );
- [DllImport( "coredll.dll" )]
- private static extern IntPtr LocalAlloc( uint flags, uint cb );
- [DllImport( "coredll.dll" )]
- private static extern IntPtr LocalFree( IntPtr hMem );
- [DllImport( "coredll.dll" )]
- private static extern IntPtr CreateDIBSection( IntPtr hdc, IntPtr hdr, uint colors, ref IntPtr pBits, IntPtr hFile, uint offset );
Add Comment
Please, Sign In to add comment