以下代码从framebuffer创建一个jpeg(在readpixels之后,是openGL库的一个函数)。
问题是创建的jpeg(test.jpeg)向左旋转了180度。
你能告诉我错误在哪里吗?
void CTaksiOGL::GetFrameFullSize(CVideoFrame& frame)
{
// Gets current frame to be stored in video file.
// select back buffer
s_glReadBuffer(GL_BACK);
// read the pixels data
s_glReadPixels(0, 0, frame.m_Size.cx, frame.m_Size.cy, GL_RGB, GL_UNSIGNED_BYTE, frame.m_pPixels);
// Adjust pixel encodings: RGB -> BGR
SwapColorComponents(frame.m_pPixels, frame.m_Size.cx, frame.m_Size.cy);
FILE* outfile = fopen("C:\\testgrab\\test.jpeg", "wb");
struct jpeg_compress_struct cinfo;
struct jpeg_error_mgr jerr;
cinfo.err = jpeg_std_error(&jerr);
jpeg_create_compress(&cinfo);
jpeg_stdio_dest(&cinfo, outfile);
GLubyte* flip = new GLubyte[sizeof(GLubyte)*frame.m_Size.cx*frame.m_Size.cy*3];
cinfo.image_width = frame.m_Size.cx;
cinfo.image_height = frame.m_Size.cy;
cinfo.input_components = 3;
cinfo.in_color_space = JCS_RGB;
int width=frame.m_Size.cx;
int height=frame.m_Size.cy;
jpeg_set_defaults(&cinfo);
/*set the quality [0..100] */
jpeg_set_quality (&cinfo, 75, true);
jpeg_start_compress(&cinfo, true);
JSAMPROW row_pointer; /* pointer to a single row */
// OpenGL writes from bottom to top.
// libjpeg goes from top to bottom.
// flip lines.
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
flip[(y*height+x)*3] = frame.m_pPixels[((width-1-y)*height+x)*3];
flip[(y*height+x)*3+1] = frame.m_pPixels[((width-1-y)*height+x)*3+1];
flip[(y*height+x)*3+2] = frame.m_pPixels[((width-1-y)*height+x)*3+2];
}
}
while (cinfo.next_scanline < cinfo.image_height) {
row_pointer = (JSAMPROW) &frame.m_pPixels[cinfo.next_scanline*width*3];
jpeg_write_scanlines(&cinfo, &row_pointer, 1);
}
jpeg_finish_compress(&cinfo);
jpeg_destroy_compress(&cinfo);
fclose(outfile);
}
答案 0 :(得分:4)
有一个错误:flip[(y*height+x)*3]
- &gt;索引原始2d数组的规范方法是y*with+x
。如果没有此修复程序,您迟早会遇到缓冲区溢出。单个“y”不是“高度”像素宽,而是“宽度”像素。同样适用于任务的右侧。
除此之外:你确定图像旋转了吗?那么问题将暂时解决(当然,在上述修正之后),如果你不仅镜像y,而且还镜像x。
如果这些公式让您感到困惑,请逐步推导出坐标,例如
const int x0 = x,
x1 = (width-1) - x;
...
target [x0 + y0*width] = source [x1 + y1*width];
答案 1 :(得分:2)
听起来有一个坐标系统变化:也许当你将字节从flip
复制到frame
时,你必须反转y坐标顺序。
答案 2 :(得分:2)
glReadPixels从帧缓冲区返回像素数据,从左下角位于(x,y)的像素开始,从位置数据开始返回客户端内存。显示时,大多数框架(我知道Qt会这样做),以其他方式对待 - (0,0)是左上角。
因此,在显示(或转换)图像时,您可能没有考虑到这一点。