读/写简单的BMP图像C++

3

我正在尝试读取简单的BMP文件,并且在不执行任何操作的情况下将其再次写回到文件中。

我不知道读取文件或将其写回时出了什么错误。 我在读取和写入时都添加了填充。

-- 文件读取 --。

std::vector<char> tempImageData;
/*tempImageData.resize(m_bmpInfo->imagesize);
file.seekg(m_bmpHeader->dataoffset);
file.read(&tempImageData[0], m_bmpInfo->imagesize);
file.close();*/
tempImageData.resize(m_bmpInfo->imagesize);
int padding = 0;
while (((m_bmpInfo->width*3+padding) % 4) != 0 )
    padding++;
for(unsigned int i = 0 ; i < m_bmpInfo->height ; i++)
{
    file.seekg(m_bmpHeader->dataoffset + i*(m_bmpInfo->width*3 + padding));
    file.read(&tempImageData[i*m_bmpInfo->width*3], i*m_bmpInfo->width*3);
}
file.close();
//bitmaps are stored as BGR -- lets convert to RGB
assert(m_bmpInfo->imagesize % 3 == 0);

for (auto i = tempImageData.begin(); i != tempImageData.end(); i+=3)
{
    m_data_red.push_back(*(i+2));
    m_data_green.push_back(*(i+1));
    m_data_blue.push_back(*(i+0));
}

-- 编写代码
file.write(reinterpret_cast<const char*>(m_bmpHeader), sizeof(BITMAPFILEHEADER));
file.write(reinterpret_cast<const char*>(m_bmpInfo), sizeof(BITMAPINFOHEADER));

// this is wrong.. format asks for bgr.. we are putting all r, all g, all b
std::vector<char> img;
img.reserve(m_data_red.size() + m_data_green.size() + m_data_blue.size());

for(unsigned int i = 0 ; i < m_data_red.size() ; i++)
{
    img.push_back(m_data_blue[i]);
    img.push_back(m_data_green[i]);
    img.push_back(m_data_red[i]);
}

char bmppad[3] = {0};

for(unsigned int i = 0 ; i < m_bmpInfo->height ; i++)
{
    // maybe something is wrong
    file.write(reinterpret_cast<const char*>(&img[i*m_bmpInfo->width*3]), m_bmpInfo->width * 3 * sizeof(unsigned char));
    file.write(bmppad, 1 * ((4-(m_bmpInfo->width*3)%4)%4) * sizeof(char));
}

file.close();

但是结果很奇怪。

Output image------Input image

enter image description here Input Image


1
你是以二进制模式打开文件的吗?你漏掉了那段代码。 - user3344003
是的,以二进制模式打开。这段代码太长了,我感到有点难过,因为我不知道问题可能出在哪里,而且我必须发布如此巨大的代码。 - user2705939
也许尝试使用unsigned char而不是char? - 1.618
@1.618,我已经尝试过了,结果一样;顺便问一下,你是指在写入文件时吗? - user2705939
根据定义,sizeof(char) 总是为1,因此您可以简化一下,将其省略掉。 - Mark Ransom
1个回答

5

由于填充被添加到每一行中,我认为您需要更改这一行:

file.seekg(m_bmpHeader->dataoffset + i*m_bmpInfo->width*3 + padding);

转换为:

file.seekg(m_bmpHeader->dataoffset + i*(m_bmpInfo->width*3 + padding));

保存计算出来的填充值可能比以两种不同的方式进行计算更容易。

编辑: 没有所有要调试的代码,有点难以准确定位,但是这一行存在错误:

file.read(&tempImageData[i*m_bmpInfo->width*3], i*m_bmpInfo->width*3);

在您读取的数量中,不应该包含*部分。这意味着在第200行,您将将200行数据读入数组中,可能会覆盖数组的末尾。一旦您超过图像的一半,这是有趣的,考虑到您的输出。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接