save opengl buffer with freeimage

I couldn’t get DevIL or corona to work on linux (the current builds seem to be broken?) so I’m trying to use freeimage. Is there a better image library to use?

I have used glReadPixels to create a GLvoid *imageData, and all I want to do is save it to a bmp file.

This looks like the function I want - is it?

FIBITMAP *FreeImage_ConvertFromRawBits(imageData, WIDTH, HEIGHT, 3, 8, unsigned red_mask, unsigned green_mask, unsigned blue_mask, false);

What do I pass as “red_mask” etc? The documentation is terribly unclear.



Why don’t you ask at FreeImage boards? This question is not about GL…

I did ask there, but I figured as everyone here uses opengl someone may have an idea how to do this / a better way to do this.

probably the bitperpixel, red_mask, etc should be used like this :

hypothesis for RGB8 :
bpp = 24
red_mask = 0xFF0000
green_mask = 0x00FF00
blue_mask = 0x0000FF

If the colors come wrong, try to exchange the red and blue mask to read BGR.

getting closer:

	BYTE pixels [3*WIDTH*HEIGHT];
	glReadPixels(0,0,WIDTH,HEIGHT, GL_RGB, GL_BYTE, pixels);
	FIBITMAP* Image = FreeImage_ConvertFromRawBits(pixels, WIDTH, HEIGHT, 3, 8, 0xFF0000, 0x00FF00, 0x0000FF, false); 
	FreeImage_Save(FIF_BMP, Image, "test.bmp", 0);

This code compiles and runs, and even produces an image file! but the image consists of only black pixels when there is in fact a scene drawn on the screen. I turned off double buffering to make sure that it was not grabbing the wrong buffer or something.

anything look wrong?


I had a couple of problems - first, I should have created a 24 bit (3*8) FIBITMAP, not an 8 bit one.

Second, I passed 3 as the pitch value. This parameter determines the number of bytes between one point in a scanline and the same point in the next scanline, including any padding (if any). If you have a pointer, pointing to the first pixel in your first scanline, after adding ‘pitch’ to it, it will point to the first point in the second scanline. (Thanks to Carston!)

The correct line should be:
FIBITMAP* Image1 = FreeImage_ConvertFromRawBits(pixels, WIDTH, HEIGHT, 3*WIDTH, 24, 0xFF0000, 0x00FF00, 0x0000FF, false);

also I used GL_BGR instead of GL_RGB because I guess openGL stores the colors in an odd order?

However, I am still having one problem. The saved image is “darker” than the image that is displayed by openGL. (see examples below). Is there any reason that would be the case?




glReadPixels(0,0,WIDTH,HEIGHT, GL_BGR, GL_UNSIGNED_BYTE, pixels);

will fix the problem.