详情可见下文
BMP结构
BITMAPFILEHEADER bmfh; --文件头
BITMAPINFOHEADER bmih; --信息表
RGBQUAD aColors[]; --颜色表
BYTE aBitmapBits[]; --颜色数据
struct A{
char type[2]; /* Magic identifier */
unsigned long size; /* File size in bytes */
unsigned short int reserved1, reserved2;
unsigned long offset; /* Offset to image data, bytes */
};
char type[2]; /* Magic identifier */
unsigned long size; /* File size in bytes */
unsigned short int reserved1, reserved2;
unsigned long offset; /* Offset to image data, bytes */
};
struct B{
unsigned long size; /* Header size in bytes */
unsigned long width,height; /* Width and height of image */
unsigned short int planes; /* Number of colour planes */
unsigned short int bits; /* Bits per pixel */
unsigned long compression; /* Compression type */
unsigned long imagesize; /* Image size in bytes */
unsigned long xresolution,yresolution; /* Pixels per meter */
unsigned long ncolours; /* Number of colours */
unsigned long importantcolours; /* Important colours */
};
unsigned long size; /* Header size in bytes */
unsigned long width,height; /* Width and height of image */
unsigned short int planes; /* Number of colour planes */
unsigned short int bits; /* Bits per pixel */
unsigned long compression; /* Compression type */
unsigned long imagesize; /* Image size in bytes */
unsigned long xresolution,yresolution; /* Pixels per meter */
unsigned long ncolours; /* Number of colours */
unsigned long importantcolours; /* Important colours */
};
以上是C语言的结构定义,下面是结构的含义,英文很简单,就不多说了。
The BITMAPFILEHEADER:
start size name stdvalue purpose
1 2 bfType 19778 must always be set to 'BM' to declare that this is a .bmp-file.
3 4 bfSize ?? specifies the size of the file in bytes.
7 2 bfReserved1 0 must always be set to zero.
9 2 bfReserved2 0 must always be set to zero.
11 4 bfOffBits 1078 specifies the offset from the beginning of the file to the bitmap data.
start size name stdvalue purpose
1 2 bfType 19778 must always be set to 'BM' to declare that this is a .bmp-file.
3 4 bfSize ?? specifies the size of the file in bytes.
7 2 bfReserved1 0 must always be set to zero.
9 2 bfReserved2 0 must always be set to zero.
11 4 bfOffBits 1078 specifies the offset from the beginning of the file to the bitmap data.
The BITMAPINFOHEADER:
start size name stdvalue purpose
15 4 biSize 40 specifies the size of the BITMAPINFOHEADER structure, in bytes.
19 4 biWidth 100 specifies the width of the image, in pixels.
23 4 biHeight 100 specifies the height of the image, in pixels.
27 2 biPlanes 1 specifies the number of planes of the target device, must be set to zero.
29 2 biBitCount 8 specifies the number of bits per pixel.
31 4 biCompression 0 Specifies the type of compression, usually set to zero (no compression).
35 4 biSizeImage 0 specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero.
39 4 biXPelsPerMeter 0 specifies the the horizontal pixels per meter on the designated targer device, usually set to zero.
43 4 biYPelsPerMeter 0 specifies the the vertical pixels per meter on the designated targer device, usually set to zero.
47 4 biClrUsed 0 specifies the number of colors used in the bitmap, if set to zero the number of colors is calculated using the biBitCount member.
51 4 biClrImportant 0 specifies the number of color that are 'important' for the bitmap, if set to zero, all colors are important.
start size name stdvalue purpose
15 4 biSize 40 specifies the size of the BITMAPINFOHEADER structure, in bytes.
19 4 biWidth 100 specifies the width of the image, in pixels.
23 4 biHeight 100 specifies the height of the image, in pixels.
27 2 biPlanes 1 specifies the number of planes of the target device, must be set to zero.
29 2 biBitCount 8 specifies the number of bits per pixel.
31 4 biCompression 0 Specifies the type of compression, usually set to zero (no compression).
35 4 biSizeImage 0 specifies the size of the image data, in bytes. If there is no compression, it is valid to set this member to zero.
39 4 biXPelsPerMeter 0 specifies the the horizontal pixels per meter on the designated targer device, usually set to zero.
43 4 biYPelsPerMeter 0 specifies the the vertical pixels per meter on the designated targer device, usually set to zero.
47 4 biClrUsed 0 specifies the number of colors used in the bitmap, if set to zero the number of colors is calculated using the biBitCount member.
51 4 biClrImportant 0 specifies the number of color that are 'important' for the bitmap, if set to zero, all colors are important.
根据C语言,我重新定义了C#下的结构,在定义结构时,请注意使用StructLayout属性来指示编译器如何定义结构,
因为CPU为了进行优化处理,会自动进行对称处理,结果struct大小会出乎你理料之外。可参见
Mastering structs in C#
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct Header
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
char [] type ; //位图类型 2字节
uint size; //ulong size; //文件大小
ushort reserved1, reserved2; //文件保留字,为0
uint offset;// ulong offset; //位图起始位置
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct InforHeader
{
uint size;// ulong size; //结构占用字节数
public uint width, height;// ulong width, height; //宽度,高度
ushort planes; //目标设备级别
public ushort bits; //像素位数 1双色,4 16色,8 256色 24真柴色
uint compression;// ulong compression; //压缩类型 0, 1, 2
uint imagesize;// ulong imagesize; //位图大小
uint xresolution, yresolution; //ulong xresolution, yresolution; //分辨率,象素数
uint ncolors;// ulong ncolors; //颜色数
uint importantcolors;// ulong importantcolors; //重要颜色数
}
struct Header
{
[MarshalAs(UnmanagedType.ByValArray, SizeConst=2)]
char [] type ; //位图类型 2字节
uint size; //ulong size; //文件大小
ushort reserved1, reserved2; //文件保留字,为0
uint offset;// ulong offset; //位图起始位置
}
[StructLayout(LayoutKind.Sequential, Pack=1)]
struct InforHeader
{
uint size;// ulong size; //结构占用字节数
public uint width, height;// ulong width, height; //宽度,高度
ushort planes; //目标设备级别
public ushort bits; //像素位数 1双色,4 16色,8 256色 24真柴色
uint compression;// ulong compression; //压缩类型 0, 1, 2
uint imagesize;// ulong imagesize; //位图大小
uint xresolution, yresolution; //ulong xresolution, yresolution; //分辨率,象素数
uint ncolors;// ulong ncolors; //颜色数
uint importantcolors;// ulong importantcolors; //重要颜色数
}
在BMP结构中,要注意的是当BMP使用24bit model时,颜色表不再存在了,每个像素使用三个byte来表示RGB,从36H(54)的位置
开始存放像素信息。
以下是从BMP文件中读取信息。
FileStream file = File.OpenRead("c:\\test1.bmp");
BinaryReader br = new BinaryReader(file);
byte[] buffheader = new byte[Marshal.SizeOf(typeof(Header))];
byte[] buffInfoheader = new byte[Marshal.SizeOf(typeof(InforHeader))];
int amt = 0;
amt += file.Read(buffheader, amt, buffheader.Length);
long i = file.Position;
GCHandle handle = GCHandle.Alloc(buffheader, GCHandleType.Pinned);
Header header = (Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
typeof(Header));
handle.Free();
amt += file.Read(buffInfoheader, 0, buffInfoheader.Length);
i = file.Position;
handle = GCHandle.Alloc(buffInfoheader, GCHandleType.Pinned);
InforHeader infoheader = (InforHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
typeof(InforHeader));
handle.Free();
//24位真彩没有颜色表,直接读颜色数据
byte [] buffData = new byte[infoheader.height*infoheader.width*3];
amt += file.Read(buffData, 0, buffData.Length);
BinaryReader br = new BinaryReader(file);
byte[] buffheader = new byte[Marshal.SizeOf(typeof(Header))];
byte[] buffInfoheader = new byte[Marshal.SizeOf(typeof(InforHeader))];
int amt = 0;
amt += file.Read(buffheader, amt, buffheader.Length);
long i = file.Position;
GCHandle handle = GCHandle.Alloc(buffheader, GCHandleType.Pinned);
Header header = (Header)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
typeof(Header));
handle.Free();
amt += file.Read(buffInfoheader, 0, buffInfoheader.Length);
i = file.Position;
handle = GCHandle.Alloc(buffInfoheader, GCHandleType.Pinned);
InforHeader infoheader = (InforHeader)Marshal.PtrToStructure(handle.AddrOfPinnedObject(),
typeof(InforHeader));
handle.Free();
//24位真彩没有颜色表,直接读颜色数据
byte [] buffData = new byte[infoheader.height*infoheader.width*3];
amt += file.Read(buffData, 0, buffData.Length);
C#中有丰富的处理图形的类,使用以上代码的机会并不多,只是喜欢C#才去改写C代码。