使用 qdbmp 读取.bmp 图像

Posted

技术标签:

【中文标题】使用 qdbmp 读取.bmp 图像【英文标题】:read.bmp image using qdbmp 【发布时间】:2018-05-15 14:15:58 【问题描述】:

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

这是link图书馆

这是我的代码:

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
.....

有人可以帮忙吗?

编辑

这是link to the image(选择 Lena,8 位灰色 (512 x 512),bmp )

【问题讨论】:

与您的问题无关,但 "%lu" 格式说明符适用于 unsigned long int。变量widthheightunsigned int,您不应在格式说明符中使用l 前缀。 是编译器建议我更改它...但你是对的 @Some 程序员老兄实际上该库的文档说UINTUINT - Unsigned long integer (DWORD) 可能库不支持bmp图像的格式,它支持Uncompressed 32 BPP、Uncompressed 24 BPP和Uncompressed 8 BPP。您必须确保您的图像是其中一种形式。 我们跑题了,问题的主要原因一定是库不理解bmp图像变体。 【参考方案1】:

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

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

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

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>

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

【讨论】:

以上是关于使用 qdbmp 读取.bmp 图像的主要内容,如果未能解决你的问题,请参考以下文章

6.3.3 读取BMP图片信息

Tensorflow:如何编码和读取 bmp 图像?

Bmp图像的数据格式及读取

用c语言读取24位位图bmp文件

读取 BMP 文件 C++(读取 BMP 标头时出现问题)

读取 .bmp 图像并从图像的第 10 个字节中减去 10 并在 Java 中重新创建图像