2012-05-07 72 views
2

我需要一种简单的方法将包含RGB数据的缓冲区转换为jpeg。我已经尝试过使用libjpeg,但我根本无法让它正常工作。例如,在保存缓冲区作为位图产生这样的:RGB缓冲区到JPEG缓冲区,这里有什么问题?

Bitmap Screenshot

使用的libjpeg编码在存储器中的相同图像产生这样的:

enter image description here

并直接保存图像到文件只是中止没有发出警告,错误或任何事情。

我当然需要一些可行的东西!

这是我在做什么

void OnKeyPress(unsigned char key, int x, int y) { 
    if (key != static_cast<unsigned char>('p')) 
    return; 

    int width = g_current_width; 
    int height = g_current_height; 
    boost::scoped_array<boost::uint8_t> buffer(new boost::uint8_t[3 * width * height]); 

    glReadBuffer(GL_FRONT); 
    glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, 
       reinterpret_cast<GLvoid *>(buffer.get())); 
    glReadBuffer(GL_BACK); 

    FlipImage(buffer.get(), width, height); 

    // Generate a BMP files for testing purposes 
    SaveRGB("screenshot.bmp", buffer.get(), width, height); 

    jpeg_compress_struct cinfo; 
    jpeg_error_mgr jerr; 
    cinfo.err = jpeg_std_error(&jerr); 
    jerr.trace_level = 10; 
    jpeg_create_compress(&cinfo); 
    boost::uint8_t *jpeg_buffer_raw = NULL; 
    unsigned long outbuffer_size = 0; 
    jpeg_mem_dest(&cinfo, &jpeg_buffer_raw, &outbuffer_size); 

    cinfo.image_width = width; 
    cinfo.image_height = height; 
    cinfo.input_components = 3; 
    cinfo.in_color_space = JCS_RGB; 
    jpeg_set_defaults(&cinfo); 

    jpeg_set_quality(&cinfo, 100, true); 
    jpeg_start_compress(&cinfo, true); 
    int row_stride = width * 3; 
    JSAMPROW row_pointer[1]; 
    int counter = 0; 
    std::cout << boost::format("height: %d\n") % height; 
    boost::uint8_t *r_buffer = buffer.get(); 
    while (cinfo.next_scanline < cinfo.image_height) { 
    row_pointer[0] = &r_buffer[cinfo.next_scanline * row_stride]; 
    jpeg_write_scanlines(&cinfo, row_pointer, 1); 
    std::cout << boost::format("current line: %d\n") % (counter++); 
    } 
    jpeg_finish_compress(&cinfo); 
    jpeg_destroy_compress(&cinfo); 
    std::ofstream jpegfile("screenshot.jpg"); 
    jpegfile.write(reinterpret_cast<const char*>(jpeg_buffer_raw), outbuffer_size); 
    jpegfile.flush(); 
    // calling free(jpeg_buffer_raw); or delete[] jpeg_buffer_raw; generates an error 
} 
+3

怎么样你叫libjpeg?向我们展示代码。 – Thomas

+1

SO是一个问答网站。你的问题是什么? –

+0

SO伙计们,我用我使用的代码更新了这个问题。 – Sambatyon

回答

2

所以,我发现这个问题,这是在最后,输出文件应该已经初始化是这样的:

std::ofstream jpegfile("screenshot.jpg", std::ios_base::out | std::ios_base::binary);