简体   繁体   中英

How to write frame buffer data in to a JPEG or BMP image

I am new to openGl, i have a task to write the frame buffer(opengl offscreen rendering data) into JPG or Bmp image.

I google it but unable to find the right solution...

I have tried the following code,but result was an unsupported file.I couldn't able to open the file.

FILE *Out;
    unsigned char *Buff;

    // Capture a screen shot. Save as a RAW-format file.
    // First, allocate memory.
    Buff = new unsigned char[512*512*3];

   // Now, get pixels.
    glReadBuffer(GL_BACK);
    glReadPixels(0,0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Buff);

  // Now, open to file and write pixels.
   Out = fopen(Filename, "wb");
   if(!Out) return;
   fwrite(Buff, 3, 512*512, Out);


   fclose(Out);
   delete[] Buff;

Here i used raw file but what i want is jpeg or bmp file.

You were or the right path.

First things first, do not declare variables (especially pointers) uninitialized it can result in the program malfunction (for more please read : https://softwareengineering.stackexchange.com/questions/223862/how-important-is-to-initialize-a-variable )

So instead of doing :

unsigned char *Buff;
Buff = new unsigned char[512*512*3];

Do :

unsigned char *Buff=new unsigned char[512*512*3];

Your buff needs to be byte*. If you want to write to a BMP file you need to have in your header the following:

#include <Windows.h>

Now you can save to bitmap files using BITMAPFILEHEADER and BITMAPINFOHEADER. Your new code should look like this.

    byte* Buff = new byte[512*512*3];
if (!Buff)
    return;

glReadBuffer(GL_BACK);
glReadPixels(0, 0, 512, 512, GL_RGB, GL_UNSIGNED_BYTE, Buff);


FILE *Out = fopen(filename, "wb");
if (!Out)
    return;
BITMAPFILEHEADER bitmapFileHeader;
BITMAPINFOHEADER bitmapInfoHeader;

bitmapFileHeader.bfType = 0x4D42;
bitmapFileHeader.bfSize = windowWidth*windowHeight * 3;
bitmapFileHeader.bfReserved1 = 0;
bitmapFileHeader.bfReserved2 = 0;
bitmapFileHeader.bfOffBits =
    sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);

bitmapInfoHeader.biSize = sizeof(BITMAPINFOHEADER);
bitmapInfoHeader.biWidth = windowWidth - 1;
bitmapInfoHeader.biHeight = windowHeight - 1;
bitmapInfoHeader.biPlanes = 1;
bitmapInfoHeader.biBitCount = 24;
bitmapInfoHeader.biCompression = BI_RGB;
bitmapInfoHeader.biSizeImage = 0;
bitmapInfoHeader.biXPelsPerMeter = 0; // ?
bitmapInfoHeader.biYPelsPerMeter = 0; // ?
bitmapInfoHeader.biClrUsed = 0;
bitmapInfoHeader.biClrImportant = 0;

fwrite(&bitmapFileHeader, sizeof(BITMAPFILEHEADER), 1, Out);
fwrite(&bitmapInfoHeader, sizeof(BITMAPINFOHEADER), 1, Out);
fwrite(Buff, windowWidth*windowHeight * 3, 1, Out);
fclose(Out);

delete[] Buff;

( Code from : http://dave.thehorners.com/tech-talk/programming/124-opengl-writing-the-framebuffer-to-disk )

To convert to BMP, you want to create an empty bitmap the right size in 24bpp format, then copy each row of the GL_RGB data to its pixel array. (Remember that BMPs store the rows from bottom up and pad each row to a multiple of 4 bytes.) The easiest way to convert to JPEG is probably to create a BMP in memory and compress it. There are several graphics libraries that will help.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM