CImg图像为无色
CImg Image is Colorless
目前,我正在完善我的基层编辑器程序中的一个函数,该函数允许我保存我创建的映射。它会吐出生成的地图的.bmp图像。它通过我刚刚发现的一个名为CImg的库来实现这一点,我对此一无所知。一切似乎都正常,但生成的.bmp图像没有着色,而是以不同的黑白色调显示。就像我说的,我对图书馆基本一无所知,所以如果你知道这里可能有什么问题,我会很感激你的帮助。
这是保存功能:
void Map::Save() {
Vertex top_left_most, top_right_most, bottom_left_most;
int img_w = 0, img_h = 0;
std::vector<std::pair<GLuint, GLuint>>::iterator tl = bufferIDs.begin(); //This little block gives the _most variables valid starting vals
glBindBuffer(GL_ARRAY_BUFFER, tl->second);
glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), &top_left_most);
top_right_most = bottom_left_most = top_left_most;
for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) { //SEEKS TOP LEFT MOST TILE ON MAP
Vertex current_coord;
glBindBuffer(GL_ARRAY_BUFFER, i->second);
glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), ¤t_coord);
if ((current_coord.x < top_left_most.x && current_coord.y < top_left_most.y) ||
(current_coord.x == top_left_most.x && current_coord.y < top_left_most.y) ||
(current_coord.x < top_left_most.x && current_coord.y == top_left_most.y)) {
top_left_most = current_coord;
}
}
for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) { //SEEKS TOP RIGHT MOST TILE ON MAP
Vertex current_coord;
glBindBuffer(GL_ARRAY_BUFFER, i->second);
glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), ¤t_coord);
if ((current_coord.x > top_right_most.x && current_coord.y < top_right_most.y) ||
(current_coord.x == top_right_most.x && current_coord.y < top_right_most.y) ||
(current_coord.x > top_right_most.x && current_coord.y == top_right_most.y)) {
top_right_most = current_coord;
}
}
for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) { //SEEKS BOTTOM LEFT MOST TILE ON MAP
Vertex current_coord;
glBindBuffer(GL_ARRAY_BUFFER, i->second);
glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), ¤t_coord);
if ((current_coord.x < bottom_left_most.x && current_coord.y > bottom_left_most.y) ||
(current_coord.x == bottom_left_most.x && current_coord.y > bottom_left_most.y) ||
(current_coord.x < bottom_left_most.x && current_coord.y == bottom_left_most.y)) {
bottom_left_most = current_coord;
}
}
img_w = (top_right_most.x + 64) - top_left_most.x; //Calculating image dimensions for the buffer
img_h = (bottom_left_most.y + 64) - top_left_most.y;
GLuint *image = new GLuint[img_w * img_h]; //Creating the image buffer
int int_start_x = 0; //start_x and y that will be used in buffer pointer positioning computations
int int_start_y = 0;
//these nested fors fill the buffer
for (GLfloat start_y = top_left_most.y; start_y != bottom_left_most.y + 64; start_y += 64) {
for (GLfloat start_x = top_left_most.x; start_x != top_right_most.x + 64; start_x += 64) {
bool in_map = false;
std::vector<std::pair<GLuint, GLuint>>::iterator valid_tile;
for (auto i = bufferIDs.begin(); i != bufferIDs.end(); ++i) { //This for checks to see if tile corresponding to start_x & y is present in map
Vertex current_tile_pos;
glBindBuffer(GL_ARRAY_BUFFER, i->second);
glGetBufferSubData(GL_ARRAY_BUFFER, sizeof(TextureCoord), sizeof(Vertex), ¤t_tile_pos);
if (current_tile_pos.x == start_x && current_tile_pos.y == start_y) {
in_map = true;
valid_tile = i;
break;
}
}
GLuint *imagepos = image; //Repositioning the pointer into the final image's buffer
imagepos += int_start_x + (int_start_y * img_w);
if (in_map) { //if in map, that tile's texture is used to fill the corresponding part of the image buffer
GLuint *texture = new GLuint[64 * 64];
glBindTexture(GL_TEXTURE_2D, valid_tile->first);
glGetTexImage(GL_TEXTURE_2D, 0, GL_RGBA, GL_UNSIGNED_BYTE, texture);
GLuint *texturepos = texture;
for (GLuint ypos = 0; ypos != 64; ++ypos) {
std::memcpy(imagepos, texturepos, 64 * 4);
texturepos += 64;
imagepos += img_w;
}
if (texture)
delete[] texture;
}
else { //otherwise, a default all-black array is used to fill the corresponding untiled part of the image buffer
GLuint *black_buffer = new GLuint[64 * 64];
GLuint *blackpos = black_buffer;
GLuint solid_black;
char *p = (char *)&solid_black;
p[0] = 0;
p[1] = 0;
p[2] = 0;
p[3] = 255;
for (GLuint i = 0; i != 64 * 64; ++i) {
black_buffer[i] = solid_black;
}
for (GLuint ypos = 0; ypos != 64; ++ypos) {
std::memcpy(imagepos, blackpos, 64 * 4);
blackpos += 64;
imagepos += img_w;
}
if (black_buffer)
delete[] black_buffer;
}
int_start_x += 64;
}
int_start_x = 0;
int_start_y += 64;
}
cimg_library::CImg<GLuint> final_image(image, img_w, img_h); //no color!!
final_image.save_bmp("map.bmp");
if (image)
delete[] image;
}
在某些解释有帮助的情况下,Vertex
是两个GLfloat
的简单struct
(与TextureCoord
一样),bufferIDs
是GLuint
的std::pair
的std::vector
,第一个表示纹理ID,第二个表示VBO ID。
以下是请求的样本图像:
图像应该是什么样子(这是单色的)
与上面的图像完全相同,但使用interpret_cast方法
您的线路
cimg_library::CImg<GLuint> final_image(image, img_w, img_h);
如果您期望彩色图像,则是错误的,因为这会创建单通道图像。你需要在最后加一个3来制作3个通道——一个用于红色,一个用于绿色,还有一个用于蓝色。
此外,您的数据存储在GLuint
中,这意味着4x2像素的图像将像这样存储,即按像素进行带交织:
RGBA RGBA RGBA RGBA
RGBA RGBA RGBA RGBA
而CImg希望将其存储在平面方式交织的频带中:
RRRRRRRR
GGGGGGGG
BBBBBBBB
AAAAAAAA
此链接解释CImg内存缓冲区的布局。
相关文章:
- C++,OpenCV,尝试显示图像时"OpenCV(4.3.0) Error: Assertion failed (size.width>0 && size.height>0)"此错误
- 如何使用OpenCV将RBG图像转换为HSV,并将H、S和V值保存为C++中的3个独立图像
- OpenCV EqualizeHist()从彩色图像创建黑白图像
- 将"打开的CV图像"中的"颜色"转换为整数格式
- 如何使用CImg打开图像?
- CImg阅读图像
- 如何使用CIMG.H库在另一个图像上显示一个图像
- 如何将CIMG图像对象从C /CLI传递到C#
- 示例文件中的CImg图像加载错误
- CImg 库在旋转时创建失真的图像
- CImg保存图像会更改值
- CIMG 图像替换
- CImg - 获取图像的反向 FFT
- CImg读取图像异常
- CImg:图像二值化结果失败
- 如何使用CImg显示少量图像(每个图像在单独的窗口中)
- 我如何显示一个临时图像与CImg库
- 图像文件到矢量像素与CImg
- 对二进制图像数据的CImg
- CImg图像为无色