这里有一些可能有用的代码:
const int XPelsPerMeter = 0xb12;
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();
IntPtr sdc = GetDC( IntPtr.Zero );
IntPtr hdc = CreateCompatibleDC( sdc );
SelectObject( hdc, hbm );
byte[] arrayBytes = CreateBinary(hdc, bitmap.Height, bitmap.Width);
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;
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;
IntPtr pBi = LocalAlloc( Gptr, bi.biSize );
Marshal.StructureToPtr( bi, pBi, false );
IntPtr hBmp = CreateDIBSection( hDc, pBi, 0, ref pBits, IntPtr.Zero, 0 );
BITMAPINFOHEADER biNew = ( BITMAPINFOHEADER )Marshal.PtrToStructure( pBi, typeof( BITMAPINFOHEADER ) );
IntPtr hOldBitmap = SelectObject( hMemDc, hBmp );
BitBlt( hMemDc, 0, 0, bi.biWidth, bi.biHeight, hDc, 0, 0, Srccopy );
byte[] RealBits = new byte[cb];
Marshal.Copy( pBits, RealBits, 0, cb );
BITMAPFILEHEADER bfh = new BITMAPFILEHEADER();
uint colorSize = 2 * 4;
uint sizeofBinfo = 0x36 + colorSize;
bfh.bfSize = ( uint )( cb + sizeofBinfo );
bfh.bfType = 0x4d42;
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 );
byte[] data = new byte[cb + bfh.bfOffBits];
header.CopyTo( data, 0 );
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 );
byte[] colors = new byte[10];
colors[4] = 255;
colors[5] = 255;
colors[6] = 255;
colors.CopyTo( data, ( int )bfh.bfOffBits - ( int )colorSize );
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 );
}
要将其保存到文件中,请执行以下操作:
byte[] data = BWImage.GetByteArray(bitmap);
FileStream fs = new FileStream( "BW.bmp", FileMode.Create );
fs.Write( data, 0, data.Length );
fs.Flush();
fs.Close();