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;};
