BMP编程实践2:256色灰度图的颜色板分析

前言

        本次实验使用的BMP图片是256位的灰度图片。

一 本次实验需要的知识

第三部分-调色板
        第三部分为调色板(Palette),当然,这里是对那些需要调色板的位图文件而言的。有些位图, 如真彩色图,前面已经讲过,是不需要调色板的,BITMAPINFOHEADER 后直接是位图数据。调色板实际上是一个数组,共有 biClrUsed 个元素(如果该值为零,则有 2 的 biBitCount 次方个元素)。数组中每个元素的类型是一个 RGBQUAD 结构,占 4 个字节,其定义如下:

typedef uint8_t BYTE;
typedef struct tagRGBQUAD{
    BYTE rgbBlue; //该颜色的蓝色分量
    BYTE rgbGreen; //该颜色的绿色分量
    BYTE rgbRed; //该颜色的红色分量
    BYTE rgbReserved; //保留值
} RGBQUAD;

二 灰度图的颜色板分析

        本次实验,生成的图片是8位256色的灰度图。灰度的RGB颜色值,是R、G、B三个分量相等。如下图所示,红绿蓝红色使用相同值。

 

 编程实现256色灰度图,大概就是下面这样

typedef uint8_t BYTE;
typedef struct tagRGBQUAD{
    BYTE rgbBlue; //该颜色的蓝色分量
    BYTE rgbGreen; //该颜色的绿色分量
    BYTE rgbRed; //该颜色的红色分量
    BYTE rgbReserved; //保留值
} RGBQUAD;

int i = 0;
RGBQUAD Palette[256];
for(i = 0;i < sizeof(Palette)/sizeof(Palette[0]);i++){
    Palette[i].rgbBlue = i;
    Palette[i].rgbGreen = i;
    Palette[i].rgbRed = i;
    Palette[i].rgbReserved = 0;
}

三 完整的测试代码

#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <stdint.h>

#define IMAGE_SIZE      1280*800
#define DEV_NAME        "/dev/video1"
char read_buf[IMAGE_SIZE];

typedef uint16_t WORD;
typedef uint32_t DWORD;
#pragma pack(1)
typedef struct tagBITMAPFILEHEADER{
    WORD bfType;//2
    DWORD bfSize;//4
    WORD bfReserved1;//2
    WORD bfReserved2;//2
    DWORD bfOffBits;//4
} BITMAPFILEHEADER;
#pragma pack()
typedef uint32_t LONG;
#pragma pack(1)
typedef struct tagBITMAPINFOHEADER{
    DWORD biSize;
    LONG biWidth;
    LONG biHeight;
    WORD biPlanes;
    WORD biBitCount;
    DWORD biCompression;
    DWORD biSizeImage;
    LONG biXPelsPerMeter;
    LONG biYPelsPerMeter;
    DWORD biClrUsed;
    DWORD biClrImportant;
} BITMAPINFOHEADER;
#pragma pack()
typedef uint8_t BYTE;
#pragma pack(1)
typedef struct tagRGBQUAD{
    BYTE rgbBlue; //该颜色的蓝色分量
    BYTE rgbGreen; //该颜色的绿色分量
    BYTE rgbRed; //该颜色的红色分量
    BYTE rgbReserved; //保留值
} RGBQUAD;
#pragma pack()
void create_grey_palette(RGBQUAD *Palette,int len){
        int i = 0;

        for(i = 0;i < len;i++){
                Palette[i].rgbBlue = i;
                Palette[i].rgbGreen = i;
                Palette[i].rgbRed = i;
                Palette[i].rgbReserved = 0;
        }
}
int write_grey_bmp(char *name,char *buf)
{
        int fd = 0;
        RGBQUAD Palette[256];
        BITMAPFILEHEADER bit_map_file_header;
        BITMAPINFOHEADER bit_map_info_header;
        fd = open(name,O_RDWR | O_CREAT | O_TRUNC,0666);
        if(fd < 0){
                perror("open");
                return -1;
        }
        printf("%ld,%ld\n",sizeof(BITMAPFILEHEADER),sizeof(BITMAPINFOHEADER));
        printf("open %s ok\n",name);
        memset(&bit_map_file_header,0,sizeof(BITMAPFILEHEADER));
        memset(&bit_map_info_header,0,sizeof(BITMAPINFOHEADER));
        bit_map_file_header.bfType = 0x4D42;
        bit_map_file_header.bfSize = 1280*800 + 54 + 1024;
        bit_map_file_header.bfOffBits = 54 + 1024;//就是位图数据之前的文件头长度,包括调色板。

        write(fd,&bit_map_file_header,sizeof(BITMAPFILEHEADER));

        bit_map_info_header.biSize = 40;
        bit_map_info_header.biWidth = 1280;
        bit_map_info_header.biHeight = 800;
        bit_map_info_header.biPlanes = 1;
        bit_map_info_header.biBitCount = 8;
        bit_map_info_header.biCompression = 0;// //压缩方式,可以是0,1,2,其中0表示不压缩
        bit_map_info_header.biSizeImage = 1280*800;
        bit_map_info_header.biXPelsPerMeter = 0;
        bit_map_info_header.biYPelsPerMeter = 0;
        bit_map_info_header.biClrUsed = 256;
        bit_map_info_header.biClrImportant = 256;
        write(fd,&bit_map_info_header,sizeof(BITMAPINFOHEADER));
        create_grey_palette(Palette,sizeof(Palette)/sizeof(Palette[0]));
        write(fd,(char*)Palette,1024);
        write(fd,buf,1280*800);


        close(fd);

        return 0;
}
int main()
{
        memset(read_buf,0x55,sizeof(read_buf));
        write_grey_bmp("grey.bmp",read_buf);
        return 0;
}

四 实验结果:

lkmao@ubuntu:/big$ ./a.out
14,40
open grey.bmp ok
lkmao@ubuntu:/big$

图片属性如下所示:

 

总结

        如果想把BMP所有的细节搞清楚,确实挺不容易的,如果只是针对自己需要的部分研究研究,还是有帮助的。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

千册

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值