用 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 char
或 uint8_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
我正在尝试编写一个读取 bmp 文件然后复制它的函数。我像往常一样将图像 header 读取到结构中,并将像素值复制到 RGB 矩阵。
我正在构建的用于写入 BMP 文件的函数给出了正确的图像 width/height 和大小,但是图像全黑并且像素值都错误(我将其与通过使用 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;
}
我预计您正在编写 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 char
或 uint8_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