BMP格式结构

BMP文件的数据按照从文件头开始的先后顺序分为四个部分:

1.位图文件头(bmp file header):提供文件的格式、大小等信息
2.位图信息头(bitmap information):提供图像数据的尺寸、位平面数、压缩方式、颜色索引等信息
3.调色板(color palette):可选,如使用索引来表示图像,调色板就是索引与其对应的颜色的映射表
4.位图数据(bitmap data):图像数据区

jgtncdq.png

获取文件大小并送到内存

void displayBMP() //定义函数,用于获取文件大小
{
    FILE* fp = fopen("E:\\DATA\\tx.bmp", "r");
    if (fp == NULL)
    {
        printf("打开文件失败");
    }
    else
    {
        int fileSize = filelength(fileno(fp));  //filelength函数(根据文件号获得文件的大小)
                                                //fileno函数(根据文件获得文件号)
        if (fileSize > 1024 * 1024 * 20)        //判断文件大小是否正常
        {
            printf("文件大于20M,拒绝显示!");
        }
        else
        {
            void* fileBuffer = malloc(fileSize);//分配文件大小相同的一块内存空间并让指针指向它
            if (fileBuffer == NULL)
            {
                printf("内存不足以显示图片");
            }
            else
            {
                fread(fileBuffer, fileSize, 1, fp);//将读到的数据送到内存中
                fclose(fp);
                showBMP(fileBuffer);
            }
        }
    }
}

根据已经读入的bmp文件数据显示图片

/*根据已经读入的BMP文件数据显示图片*/
/*在调用此函数时,文件内容已经完全读入内存,指针FILE_BUFFER指向这块内存的首地址*/
void showBMP(const void* FILE_BUFFER)
{
    char* tag = (char*)FILE_BUFFER;
    BIT_MAP_HEADER* bitMapHeader = (BIT_MAP_HEADER*)(((char*)(FILE_BUFFER)) + 2);//从第三个字节开始是文件头信息
    //void* 类型的指针不能直接进行算术运算,所以先转换成char*型
    BIT_MAP_INFO* bitMapInfo = (BIT_MAP_INFO*)(((char*)(FILE_BUFFER)) + 14);//从第15个字节开始是文件像素信息(从文件头开始到图像像素数据的字节偏移量(以字节Bytes为单位),以为位图的调色板长度根据位图格式不同而变化,可以用这个偏移量快速从文件中读取图像数据)
    /*如果这个图片不是24位位图,则会存在调色板,你需要考虑设定一个指针指向调色板,便于未来使用其中的颜色*/
    char* pixelData = ((char*)(FILE_BUFFER)) + bitMapHeader->OffBits;
    //如果通过结构体的指针访问它的成员,不是使用 ".",而是使用 "->"

    initgraph(bitMapInfo->Width, bitMapInfo->Height);//初始化窗口大小

    for (int y = bitMapInfo->Height - 1; y >= 0; y--)
    {
        for (int x = 0; x <= bitMapInfo->Width - 1; x++)
        {
            /*目前,程序是按照24位位图编写的,三个字节描述一个像素的颜色*/
            /*为了支持显示单色、16色、256色图片,此处要修改*/
            int b = pixelData[0];
            int g = pixelData[1];
            int r = pixelData[2];
            putpixel(x, y, RGB(r, g, b));
            pixelData += 3; //在BMP文件格式中,为了提高存取效率,每一行的像素数据字节数均为4的倍数
            //如果这一行数据的像素数据字节数不是4的倍数,则会在后面补n个字节,达到4的倍数
        }
    }
    _getch();
    closegraph();
}

zzt.png

位图

256色位图
对于256色位图,从第55个字节开始,连续存放256个颜色的配色信息,这个称为调色板。
Q: 256种颜色需要多少字节来描述?
A: 256*3个字节

使用256色位图的好处:只需要1个字节(存储的是调色板的索引)就可以描述1个像素的颜色,使用putpixel的时候去调色板中查询。

16色位图
使用一个字节存放两个像素的数据
假如一个字节存放的是255,255对应的二进制是11111111,前四个1是存放的一种颜色的索引值,后四个1是代表着另一个颜色的索引值

单色位图
用一个字节存储8个像素的数据

最后修改:2023 年 10 月 13 日
如果觉得我的文章对你有用,请随意赞赏