c++ - 将数据从结构二进制复制到 std::vector
问题描述
我正在使用一个可以从内存中加载 BMP 图像的库。
我有一个代表 BMP 的类。
要从内存中加载,我必须提供一个指向内存中一些 BMP 格式数据的指针和一个用于该数据大小的变量。(void* data, size_t length)
我想将我的数据存储在std::vector
. (避免手动内存管理)
我试图编写一个函数来返回 a 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
的位图文件标题中。不幸的是,现在更改设计将需要大量工作,所以我宁愿不去碰它。
解决方案
三个问题:
您想要复制bytes,但该
std::copy
函数提供了一个指向BITMAPFILEHEADER
(orBITMAPINFOHEADER
) 结构的指针。您需要将指针转换为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]
。
推荐阅读
- angular - 在步骤 1 中更改输入字段时重置垫步进器步骤 2 中的值
- javascript - 错误:找不到要导入的文件或无法读取:@fortawesome/fontawesome-free,Capybara,Rails 6.0.3
- php - 警告:尝试在第 59 行的 C:\xampp\htdocs\Nice Guys\index.php 中读取布尔属性“num_rows”
- html - 在网格列中对齐项目中心
- ios - 具有多个对齐方式的 NSAttributedString
- javascript - 如何从第三个库导入 jQueryStatic?
- javascript - Api 没有在 reactJs 中获取
- nginx - NGINX Minecraft 反向代理
- html - 垂直对齐引导列表项
- c# - ASP.NET Core 根据用户的语言从注入的服务中获取不同的 JSON 数据