使用qdbmp读取.bmp图像

我正在使用一个名为qdbmc的库来读取bmp灰色图像(lena_gray.bmp)

这是图书馆的链接

这是我的代码:

int read_image(char *filename) { struct _BMP* bmp; UINT width, height; UCHAR red,green,blue; bmp = BMP_ReadFile(filename); BMP_CHECK_ERROR( stderr, -1 ); /* Get image's dimensions */ width = BMP_GetWidth( bmp ); height = BMP_GetHeight( bmp ); printf("%lu %lu \n",width,height); /* Iterate through all the image's pixels */ for (int x = 0 ; x < width ; ++x ) { for (int y = 0 ; y < height ; ++y ) { /* Get pixel's RGB values */ BMP_GetPixelRGB( bmp, x, y, &red, &green, &blue ); printf("%d \t %d \t %d \n",red,green,blue); } } return 0; } 

正确显示宽度和高度(512 x 512),但像素值正确,因为它显示全部为零。

当我使用python的imread()函数时我得到了这个:

 60 160 160 159 161 156 161 159 162 159 160 158 154 162 158 154 156 155 160 160 153 156 154 156 154 156 154 152 155 153 153 155 153 157 155 158 ..... 

有人可以帮忙吗?

编辑

这是图像的链接 (选择Lena,8位灰色(512 x 512),bmp)

两个输出都不正确。 灰度位图中的灰色颜色为:(x,x,x),其中红色,蓝色和绿色相同。 因此零是错误的。 并且60 160 160 159 161 156 ...是错误的,因为没有重复模式。

8位位图使用表格。 前54个字节是文件标题。 然后有256种颜色(每个4字节长)然后是宽度*高度字节,其中宽度必须填充,因此宽度的大小(以字节为单位)是4的倍数。

位图像素从下到上开始,首先你必须读取行(从底部开始)然后读取每一列。 此代码应为每行的前5列打印正确的输出:

 #include  #include  #include  #include  #pragma pack(push, 1) struct my_BITMAPFILEHEADER { short bfType; int bfSize; short bfReserved1; short bfReserved2; int bfOffBits; }; struct my_BITMAPINFOHEADER { int biSize; int biWidth; int biHeight; short biPlanes; short biBitCount; int biCompression; int biSizeImage; int biXPelsPerMeter; int biYPelsPerMeter; int biClrUsed; int biClrImportant; }; #pragma pack(pop) int main(void) { if(sizeof(struct my_BITMAPFILEHEADER) != 14) { printf("stop!\n"); return 0; } FILE *fp = fopen("c:\\test\\barbara_gray.bmp", "rb"); //Read file header struct my_BITMAPFILEHEADER fhdr; struct my_BITMAPINFOHEADER ihdr; fread(&fhdr, sizeof(fhdr), 1, fp); fread(&ihdr, sizeof(ihdr), 1, fp); if(fhdr.bfType == 'MB' && ihdr.biBitCount == 8 && ihdr.biPlanes == 1) { //Read table unsigned int table[256] = { 0 }; fread(table, 4, 256, fp); int w = ihdr.biWidth; int h = ihdr.biHeight; //Find width in bytes. Use a math trick to make sure it's divisble by 4 int w_in_bytes = ((w * 8 + 31) / 32) * 4; int size = w_in_bytes * h; //Read pixels unsigned char *pixels = malloc(size); fread(pixels, 1, size, fp); //Read from bottom to top: for(int row = h - 1; row >= 0; row--) { printf("%3d: ", h - 1 - row); //Read from left to right: for(int col = 0; col < w; col++) { int pos = row * w_in_bytes + col; unsigned char color_index = pixels[pos]; unsigned int clr = table[color_index]; printf("%02X%02X%02X ", clr & 0xFF, (clr >> 8) & 0xFF, (clr >> 16) & 0xFF); if(col > 5) break; } printf("\n"); } free(pixels); } printf("\n"); fclose(fp); return 0; }