用 C 写 bmp 文件给出了错误的结果

Writing bmp file in C gives wrong result

我正在尝试编写一个读取 bmp 文件然后复制它的函数。我像往常一样将图像 header 读取到结构中,并将像素值复制到 RGB 矩阵。

我正在构建的用于写入 BMP 文件的函数给出了正确的图像 width/height 和大小,但是图像全黑并且像素值都错误(我将其与通过使用 xxd).

进行十六进制转储来生成原始 bmp 图像

写入BMP文件的函数如下:

void writeBMP(BMPFILEHEADER *headerData,BMPINFOHEADER *headerInfo, int values[headerInfo->width*headerInfo->height]) {

        FILE *out;
        out = fopen("example.bmp", "wb");
        fwrite(headerData, sizeof(char), sizeof(BMPFILEHEADER), out);
        fseek(out, 14, SEEK_SET);
        fwrite(headerInfo, sizeof(char), sizeof(BMPINFOHEADER), out);
        fseek(out, 54, SEEK_SET);
        fwrite(values, sizeof(char), headerInfo->imagesize, out);
        fclose(out);
    }

我已经使用 printf 检查了 values(这是我存储像素数据的地方)并且像素值与原始图像像素匹配。但看起来 fwrite(values, sizeof(char), headerInfo->imagesize, out) 行正在将错误的数据写入文件。

编辑:我正在添加有关代码的其他详细信息

读取像素数据的函数:

RGBmatrix readPixels(char *fileName, BMPFILEHEADER *header, BMPINFOHEADER *info) {
    FILE *fp;
    int **matR, **matG, **matB;
    int RGBvalues[info->width][info->height];

    RGBmatrix values;

    matR = allocateRGB(matR, info->width, info->height);
    matG = allocateRGB(matG, info->width, info->height);
    matB = allocateRGB(matB, info->width, info->height);

    fp = fopen(fileName, "rb");
    if(fp==NULL) {
        printf("Can't open file\n");
    }

    fseek(fp, header->offset, SEEK_SET);

    for(int i = 0; i<info->width; i++) {
        for(int j=0; j<info->height;j++) {
            fread(&RGBvalues[i][j], 3, 1, fp);
        }
    }

    for(int i=0; i<info->width; i++) {
        for(int j=0; j<info->height; j++) {
            matB[i][j] =  RGBvalues[i][j] & 0xff;
            matG[i][j] = (RGBvalues[i][j]>>8) & 0xff;
            matR[i][j] = (RGBvalues[i][j]>>16) & 0xff; 
        }
    }

    values.R = matR;
    values.G = matG;
    values.B = matB;

    return values;
}

保存 BMP 数据的结构:

typedef struct RGBmatrix {
    int **R, **G, **B;
}RGBmatrix;

typedef struct BMPFILEHEADER {
    short int magicNumber;
    int bmpfSize;
    short int reserved1;
    short int reserverd2;
    int offset;
}BMPFILEHEADER;

typedef struct BMPINFOHEADER {
    unsigned int size;
    int width, height;
    unsigned short int planes;
    unsigned short int bits;
    unsigned int compression;
    unsigned int imagesize;
    int xresolution, yresolution;
    unsigned int ncolours;
    unsigned int importantcolours;
}BMPINFOHEADER;

我的主要功能:

int main(int argc, char *argv[]) {
    BMPFILEHEADER headerData;
    BMPINFOHEADER headerInfo;
    FILE *fp;
    char fileName[20];

    strcpy(fileName, argv[1]); // command line argument to bmp file

    readBMPHeader(fileName, &headerData, &headerInfo); // read header data
    RGBmatrix values = readPixels(fileName, &headerData, &headerInfo); // read pixels

    int rgbModifiedValues[headerInfo.width*headerInfo.height];

    // do stuff with RGB values and store them into rgbModified Values

    writeBMP(&headerData, &headerInfo, rgbModifiedValues);

    return 0;
}

我预计您正在编写 256 色(8 位)BMP 文件。

如果是这样,可能是因为使用 int 值,您在文件中写入的条目不正确:

  these are not 8-bit in size
  |
  v
  int values[headerInfo->width*headerInfo->height])


  fwrite(values, sizeof(char), headerInfo->imagesize, out);
                 ^
                 |
                 but here you seem to treat them as if they are

如果可用,您应该使用 unsigned charuint8_t

如果我是对的,那么您现在应该看到的图像主要是黑色(或主要是一种颜色),带有垂直或对角线条纹,并且十六进制转储应该显示非零值与一个或三个零交错;非零值本身是正确的:

Expected pixel values
12  17  4B

Integer values in memory, read as bytes:

12 0 0 0 17 0 0 0 4B 0 0 0