从帧缓冲区创建的JPEG旋转180度

时间:2011-06-20 13:53:21

标签: c++

以下代码从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);


}

3 个答案:

答案 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)是左上角。

因此,在显示(或转换)图像时,您可能没有考虑到这一点。