Take a screenshot with openGL and save it as png

I am trying to take a screenshot in full screen and save it as png. I found the code here and modified it a bit. For a screenshot, I use openGL and Glut and for saving to png gd libraries for c. All I get is black png, and I can't understand why. I searched on stackoverflow and found some posts, but unfortunately they did not help. One of them is to use glReadBuffer (GL_FRONT); instead of glReadBuffer (GL_BACK); I tried to do without them success. Here is my code:

int SVimage2file(char *filename){ int width = glutGet(GLUT_SCREEN_WIDTH); int height = glutGet( GLUT_SCREEN_HEIGHT); FILE *png; GLubyte *OpenGLimage, *p; gdImagePtr image; unsigned int r, g, b; int i,j,rgb; png = fopen(filename, "wb"); if (png == NULL) { printf("*** warning: unable to write to %s\n",filename); return 1; } OpenGLimage = (GLubyte *) malloc(width * height * sizeof(GLubyte) * 3); if(OpenGLimage == NULL){ printf("error allocating image:%s\n",filename); exit(1); } printf("Saving to: %s .\n",filename); glPixelStorei(GL_PACK_ALIGNMENT, 1); glReadBuffer( GL_FRONT); glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_BYTE, OpenGLimage); p = OpenGLimage; image = gdImageCreateTrueColor(width,height); for (i = height-1 ; i>=0; i--) { for(j=0;j<width;j++){ r=*p++; g=*p++; b=*p++; rgb = (r<<16)|(g<<8)|b; //printf("the rgb color %d\n", rgb ); gdImageSetPixel(image,j,i,rgb); } } gdImagePng(image,png); fclose(png); gdImageDestroy(image); } 

What am I missing?

+5
source share
2 answers

You can use devil image library and take a snapshot with:

 void takeScreenshot(const char* screenshotFile) { ILuint imageID = ilGenImage(); ilBindImage(imageID); ilutGLScreen(); ilEnable(IL_FILE_OVERWRITE); ilSaveImage(screenshotFile); ilDeleteImage(imageID); printf("Screenshot saved to: %s\n", screenshotFile); } takeScreenshot("screenshot.png"); 
+1
source

If you do not refuse to use the C ++ library, you should try PNGwriter ! It records pixel images by pixels and their RGB values. As the PNGwriter starts to form the left corner, while glReadPixels () starts from the bottom left, your code looks like this:

 GLfloat* OpenGLimage = new GLfloat[nPixels]; glReadPixels(0.0, 0.0, width, height,GL_RGB, GL_FLOAT, OpenGLimage); pngwriter PNG(width, height, 1.0, fileName); size_t x = 1; // start the top and leftmost point of the window size_t y = 1; double R, G, B; for(size_t i=0; i<npixels; i++) { switch(i%3) //the OpenGLimage array look like [R1, G1, B1, R2, G2, B2,...] { case 2: B = (double) pixels[i]; break; case 1: G = (double) pixels[i]; break; case 0: R = (double) pixels[i]; PNG.plot(x, y, R, G, B); if( x == width ) { x=1; y++; } else { x++; } break; } } PNG.close(); 

PS. I also tried libgd, but it seems to only convert one image file (to hard disk or memory) to a different image format. But I think this is still useful when you want to convert many PNG files to GIF format to create GIF animations.

0
source

Source: https://habr.com/ru/post/1447771/


All Articles