wind2

导航

 
BMP文件结构如下
详情可见下文
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 */
};

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         */
};
以上是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.
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.

根据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; //重要颜色数
    }

在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);
C#中有丰富的处理图形的类,使用以上代码的机会并不多,只是喜欢C#才去改写C代码。

posted on 2007-08-28 19:06  wind2  阅读(293)  评论(0编辑  收藏  举报