我正在使用一个可以从内存中加载BMP图像的库。
我有一个代表BMP的类。
要从内存中加载,我必须提供指向内存中某些BMP格式数据的指针以及该数据大小的变量。 (void* data, size_t length)
我想将数据存储在std::vector
中。 (避免手动内存管理)
我试图编写一个返回std::vector<unsigned char>
的函数,但是我认为我所获得的不是很好。
std::vector<unsigned char> BMP::BITMAP::SaveMem() const
{
// memory storage
std::vector<unsigned char> memory;
BITMAPFILEHEADER f_head;
f_head.bfType = ushort_rev(((WORD)'B' << 0x08) | ((WORD)'M' << 0x00));
f_head.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + m_width_memory * m_height;
f_head.bfReserved1 = 0;
f_head.bfReserved2 = 0;
f_head.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
// build standard bitmap file header
BITMAPINFOHEADER i_head;
i_head.biSize = sizeof(BITMAPINFOHEADER);
i_head.biWidth = m_width;
i_head.biHeight = m_height;
i_head.biPlanes = 1;
i_head.biBitCount = m_bit_count;
i_head.biCompression = 0;
i_head.biSizeImage = m_width_memory * m_height;
i_head.biXPelsPerMeter = 0;
i_head.biYPelsPerMeter = 0;
i_head.biClrUsed = 0;
i_head.biClrImportant = 0;
// alloc
memory.resize(f_head.bfSize);
std::copy(&f_head, &f_head + sizeof(f_head), memory.at(0));
std::copy(&i_head, &i_head + sizeof(i_head), memory.at(0) + sizeof(f_head));
// write data
for(unsigned int y = 0; y < m_height; ++ y)
{
std::copy(&m_data[y * m_width_memory], m_data[y * m_width_memory + 3 * m_size_x], memory.at(0) + sizeof(f_head) + sizeof(i_head));
}
}
很显然,这无法编译。我想不出std::copy
的替代方案。这真的是完成工作的正确工具吗?
要使其编译,我认为我应该将memory.at(x)
更改为memory.data() + x
...这样,我将使用原始指针-这就是为什么我不认为std::copy
是比memcpy
更好。
请问对此有何建议?这有点不合逻辑,我早些时候就知道这一要求,所以我会将像素数据存储在unsigned char
中,而位图文件头位于数据之前。不幸的是,现在更改设计将需要大量工作,因此我宁愿不去尝试。
答案 0 :(得分:1)
三个问题:
您要复制 bytes ,但是std::copy
函数提供了指向BITMAPFILEHEADER
(或BITMAPINFOHEADER
)结构的指针。您需要将指针转换为 bytes ,例如reinterpret_cast<uint8_t*>(&f_head)
。
前者会导致数据末尾的其他问题,表达式&f_head + sizeof(f_head)
实际上等于(&f_head)[sizeof(f_head)]
,并且超出了结构末尾。您还需要在此处使用字节,例如reinterpret_cast<uint8_t*>(&f_head) + sizeof f_head
。
最后一个问题是std::copy
调用的目标,因为它的类型必须与源相似,即指向uint8_t
的指针(对于我的演员来说) 。您可以通过例如&memory[0]
。第二个电话是&memory[sizeof f_head]
。