24位的bmp图存储时是3个象素一位,所以做灰度处理时是3位一个计算。而且处理的是实际宽度的数据而不是经过对齐处理的宽度。
width是原图的实际宽度如641,height是原图的高度480,w_new 经过对齐处理后的宽度644,处理实际宽度的641的数据,但存储时按644宽度存储,传入的是24位图,生成的是8位灰度图,在读实际数据时需要按24位图的存储方式读取。w_align就是24位图的宽度。
u8_t* img_ptr = (u8_t*)src;//原bmp图的数据buf
s32_t w_new = WIDTHBYTES(width * 8);//存储8位图的buf的存储宽度(对齐后的)
s32_t h_new = height;
s32_t w_align = WIDTHBYTES(width * bmp_head->img_head->bit_count);//图像的实际宽度
s32_t num = bmp_head->img_head->bit_count / 8;//字节数24位3个字节
u8_t* rslt = new u8_t[w_new * h_new];//rslt应与buf的存储大小一致要生成的是8位图的灰度图
memset(rslt, 0, w_new*h_new);
u8_t R, G, B, GRAY;
//要处理的是实际宽度的数据,而不是对齐后宽度的数据
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
R = G = B = GRAY = 0;
img_ptr = (u8_t*)src + i * w_align + j*num;
R = *img_ptr;
img_ptr++;
G = *img_ptr;
img_ptr++;
B = *img_ptr;
GRAY = (R*299 + G*587 + B*114) / 1000;
rslt[i * w_new + j] = GRAY;
}
}
灰度图像的生成:因为原图是24位的,生成8位图的时候bit_count,image_size,pixel_off,file_size都要按8位图的改
bmp_head->img_head->bit_count = 8;
int image_size = (u32_t)(WIDTHBYTES(bmp_head->img_head->width *
img_head->bit_count)) * bmp_head->img_head->height;
bmp_head->file_head->pixel_off = 1078;
bmp_head->file_head->size = sizeof(file_header) +
sizeof(img_header) + RGB_SIZE*sizeof(rgb_quad) + image_size;
FILE* target=fopen("c://hello.bmp","wb");
fwrite(bmp_head->file_head,sizeof(file_header),1,target);
fwrite(bmp_head->img_head,sizeof(img_header),1,target);
fwrite(rgb_data, sizeof(rgb_quad)*RGB_SIZE,1,target);
//fwrite(bmp_head->buf,bmp_head->img_head->width*bmp_head->img_head->height,1,target);
fwrite(rslt,image_size,1,target);
fclose(target);
bmp图的结构:
struct bmp_file_header {//位图文件头
s16_t type;//说明文件的类型.
s32_t size; //说明文件的大小,用字节为单位
s16_t reserved1;//保留,必须设置为0
s16_t reserved2;//保留,必须设置为0
s32_t pixel_off;//说明从文件头开始到实际的图象数据之间的字节的偏移量。//
//这个参数是非常有用的,因为位图信息头和调色板的长度会
//根据不同情况而变化,所以你可以用这个偏移值迅速的从文件中读取到位数据
};
struct img_header {//位图信息头
s32_t header_size;//说明BITMAPINFOHEADER结构所需要的字数。
u32_t width;//说明图象的宽度,以象素为单位
u32_t height;//说明图象的高度,以象素为单位。
s16_t planes;//为目标设备说明位面数,其值将总是被设为1
s16_t bit_count;//说明比特数/象素,其值为1、4、8、16、24、或32
s32_t compression;//说明图象数据压缩的类型
s32_t img_size;//说明图象的大小,以字节为单位。当用BI_RGB格式时,可设置为0
s32_t x_pels_per_meter;//说明水平分辨率,用象素/米表示
s32_t y_pels_per_meter;//说明垂直分辨率,用象素/米表示
s32_t clr_used;//说明位图实际使用的彩色表中的颜色索引数(设为0的话,则说明使用所有调色板项)
s32_t clr_important;//说明对图象显示有重要影响的颜色索引的数目,如果是0,表示都重要。
};
struct rgb_quad {//彩色表
u8_t rgbBlue;
u8_t rgbGreen;
u8_t rgbRed;
u8_t rgbReserved;
};
struct bmp_header {
struct bmp_file_header *file_head;
struct img_header *img_head;
struct rgb_quad *rgb;
u8_t **buf;
};