read.bmp 使用 qdbmp 的图像

read.bmp image using qdbmp

我正在使用名为 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),但像素值正确,因为它显示全为零。

当我将 imread() 函数与 python 一起使用时,我得到了这个:

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 )

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

8 位位图使用 table。前 54 个字节是文件标题。然后是 256 种颜色(每个 4 个字节长),然后是 width * height 字节,其中 width 必须被填充所以 width 的大小(以字节为单位)是 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;
}