问题描述
我找到了 Alejandro Rodriguez 关于如何创建简单位图阅读器的教程。它使用 fseek 和 fread 来读取 24 位位图的头部分,找到宽度、高度和数据偏移等相关信息,并扫描位图的数据部分。 https://elcharolin.wordpress.com/2018/11/28/read-and-write-bmp-files-in-c-c/
它有效,而且重量轻,但是当位图图像大小超过 32 像素 && 包含超过 1 行 && 宽度不能被 4 整除时开始失败。为了存储效率,位图被填充为可整除为 4 个字节。当宽度可以被四整除时,问题不存在,但是...如果我给函数一个位图,其中包含一个宽度为 42 像素、高度为 2 像素的图像,第一条扫描线读取正确,但是连续的行开始拾取应该跳过的不需要的垃圾填充。
一张 42 像素的图像在每行的末尾会有 2 像素的填充。此函数适用于 24 位深度像素,这意味着每个像素 3 个字节,在本示例中总共填充 6 个字节。
从 imageFile 的标头解析的信息似乎始终正确。我已经仔细检查了 paddedRowSize 的计算值是否正确,并且它始终显示正确的理论计算值。几个星期以来,我一直在咀嚼这个问题,但无法弄清楚。我希望有人可以深入了解发生了什么问题...
在使用 fseek 和 fread 遍历文件以扫描 imageFile 的数据部分的 for 循环中,一定存在问题导致某些填充字节在被读入 currentRowPointer 时被拾取。为什么会这样?请释放你的圣人智慧。
这是有问题的函数以及细节:
#include <stdio.h>
#include <stdlib.h>
#define DATA_OFFSET_OFFSET 0x000A
#define WIDTH_OFFSET 0x0012
#define HEIGHT_OFFSET 0x0016
#define BITS_PER_PIXEL_OFFSET 0x001C
typedef unsigned int int32;
typedef short int16;
typedef unsigned char byte;
void ReadImage(const char *fileName,byte **pixels,int32 *width,int32 *height,int32 *bytesPerPixel)
{
FILE *imageFile = fopen(fileName,"rb");
int32 dataOffset;
fseek(imageFile,DATA_OFFSET_OFFSET,SEEK_SET);
fread(&dataOffset,4,1,imageFile);
fseek(imageFile,WIDTH_OFFSET,SEEK_SET);
fread(width,HEIGHT_OFFSET,SEEK_SET);
fread(height,imageFile);
int16 bitsPerPixel;
fseek(imageFile,BITS_PER_PIXEL_OFFSET,SEEK_SET);
fread(&bitsPerPixel,2,imageFile);
*bytesPerPixel = ((int32)bitsPerPixel) / 8;
// This is the line of line of code causing my issuesint paddedRowSize =
//4 * (((*width) + 3) / 4) * (*bytesPerPixel);
//Correct line of code that makes it all work:
int paddedRowSize = (((*width) * (*bytesPerPixel) + 3) / 4) * 4;
int unpaddedRowSize = (*width)*(*bytesPerPixel);
int totalSize = unpaddedRowSize*(*height);
*pixels = (byte*)malloc(totalSize);
int i = 0;
byte *currentRowPointer = *pixels+((*height-1)*unpaddedRowSize);
for (i = 0; i < *height; i++)
{
fseek(imageFile,dataOffset+(i*paddedRowSize),SEEK_SET);
fread(currentRowPointer,unpaddedRowSize,imageFile);
currentRowPointer -= unpaddedRowSize;
}
fclose(imageFile);
}
int main() {
uint32_t width;
uint32_t height;
uint32_t bytesPerPixel;
byte *pixels;
ReadImage("please_work.bmp",&pixels,&width,&height,&bytesPerPixel);
}
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)