BMP 阅读器无法正常工作

Posted

技术标签:

【中文标题】BMP 阅读器无法正常工作【英文标题】:BMP reader not functioning correctly 【发布时间】:2015-05-12 20:36:33 【问题描述】:

我为 24 位 BMP 编写了一个小型 BMP 加载程序,它可以工作,只是它不显示颜色。一切都是灰度的,到处都有一些颜色(不是正确的颜色)。我的代码的加载器在下面

void BMP::Read(char* filename)

    FILE* f;
    unsigned char info[54];
    if ((f = fopen(filename, "rb")) == NULL) return;
    fread(info, sizeof(unsigned char), 54, f);
    m_width = *(int*)&info[18];
    m_height = *(int*)&info[22];
    m_size = 3* m_width * m_height;
    m_pdata = new unsigned char[m_size];
    fread(m_pdata, sizeof(unsigned char), m_size, f);
    fclose(f);

然后我使用以下公式访问数组:

red = m_pdata[(y * m_width + x) + 2];
blue = m_pdata[(y * m_width + x) + 0];
green = m_pdata[(y * m_width + x) + 1];

这里有什么建议吗?我认为问题出在加载功能上,但不确定。

【问题讨论】:

使用调试器 - 查看 m_pdata 的内容 - 看起来对吗? 第二个——红色、蓝色、绿色会发生什么,你如何显示它们? 很多类似问题的重复,例如Strange values when reading pixels from 24-bit bitmap 你忘了这个因素:4 * (y * m_width + x) + 0(或3 * …,不知道)。 每行末尾可能有填充,您没有考虑到。 【参考方案1】:

提取像素通道时忘记包含像素宽度:

int pixel_width = 3; // 3 bytes for 24 bit

根据Strange values when reading pixels from 24-bit bitmap,每行末尾还有填充。填充可以通过以下方式计算:

int row_padding = (4 - (m_width * pixel_width) % 4) % 4;

访问像素颜色通道的最终公式是:

red = m_pdata[(y * m_width + x) * pixel_width + y * row_padding + 2];
blue = m_pdata[(y * m_width + x) * pixel_width + y * row_padding + 0];
green = m_pdata[(y * m_width + x) * pixel_width + y * row_padding + 1];

由于行有填充,您对m_size 的计算有点太小了。您可以将行填充解释为:

m_size = pixel_width * m_width * m_height + row_padding * m_height;

【讨论】:

关闭,但不完全。填充实际上是3 - ((m_width * pixel_width) % 4) @StevenDon 实际上,填充应该是(4 - (m_width * pixel_width) % 4) % 4(我确信有一个更简单的公式,但它有效)。 啊,是的。你是对的。我更习惯计算步幅:((m_width * pixel_width) + 3) & ~3

以上是关于BMP 阅读器无法正常工作的主要内容,如果未能解决你的问题,请参考以下文章

如何判断我的RSS阅读器是否由于RSS源错误或其他原因而无法正常工作?

SwiftUI VStack 间距:无法正常工作

nvda关闭时无法使用回车键单击

无法从本地文件路径读取文本文件 - Spark CSV 阅读器

标签渲染器问题,而点击阅读更多...文本不是仅在 ios 中自动换行

无法将纹理绑定到 GL_QUADS