问题
I'm trying to take a screenshot of full screen and save it as a png. I found a code here and modified it a bit. For the screenshot I use openGL and Glut and for the saving in png the gd library for c. All I'm getting is a black png and I can't figure out why. I searched in stackoverflow and found some posts, but unfortunately they didn't help. One of them was to use glReadBuffer( GL_FRONT); instead of glReadBuffer(GL_BACK); I tryed with both of them with no 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 is it that I'm missing?
回答1:
You could use the devil image library and take a screeshot 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");
回答2:
If you don't reject to use C++ library, you should try PNGwriter! It write the picture pixel by pixel and their RGB values. Since the PNGwriter start form left-up corner while the glReadPixels() start from left-bottom, your code while like:
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 had also try libgd, but it seems only convert one image file (in the hard disk or in memory) to another format of image. But I think it still useful while you want to convert many PNG file to GIF format to create a GIF animate.
来源:https://stackoverflow.com/questions/13516424/take-screenshot-with-opengl-and-save-it-as-png