用C编写bmp文件会产生错误的结果

时间:2018-06-23 17:51:12

标签: c bmp

我正在尝试编写一个函数,该函数读取bmp文件,然后对其进行复制。我像往常一样将图像标题读取为结构,然后将像素值复制到RGB矩阵中。

我正在构建的用于写入BMP文件的功能可以提供正确的图像宽度/高度和大小,但是图像全为黑色,并且像素值都错误时(我正在将其与原始bmp图像进行比较)通过使用xxd进行十六进制转储)。

这是写入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;
}

1 个答案:

答案 0 :(得分:3)

我希望您正在编写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