2012-11-22 40 views
4

我試圖截取全屏並將其保存爲PNG。我發現一個代碼here並修改了一下。對於屏幕截圖,我使用openGL和Glut並保存爲p的gd庫。我所得到的只是一個黑色的PNG,我無法弄清楚爲什麼。我在stackoverflow中搜索並找到了一些帖子,但不幸的是他們沒有幫助。其中之一是使用glReadBuffer(GL_FRONT);而不是glReadBuffer(GL_BACK);我嘗試了兩個都沒有成功。這是我的代碼:使用openGL截圖並將其保存爲PNG

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); 
} 

什麼是我失蹤?

+1

你在哪裏以及如何渲染OpenGL framebuffer?該代碼缺失。 – datenwolf

+0

@datenwolf你是什麼意思。我沒有閱讀glReadBuffer(GL_FRONT)圖形卡的幀緩衝區? – user1656466

+0

恩,不,你正在讀的是OpenGL上下文綁定窗口的framebuffer。並且創建一個OpenGL上下文以匹配窗口的可視化。 **您不能使用OpenGL製作任意截圖。** OpenGL幀緩衝區的內容僅在OpenGL上下文綁定的可繪製內部定義,並且僅限於使用OpenGL繪製的圖像。你是否真的試圖在沒有OpenGL上下文或爲它創建的窗口的情況下進行OpenGL調用? – datenwolf

回答

1

您可以使用devil image library並採取screeshot有:

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"); 
+0

我也試圖找到一個簡單的方法來做到這一點。我試過你的代碼,但是當它到達ilSaveImage行時,我得到了一個EXC_BAD_ACCESS信號。我不知道如何進一步調試 - 任何想法? – Nathaniel

+0

我決定使用GDK代替OpenGL。也許這會幫助別人: – user1656466

0

如果你不拒絕使用C++庫,你應該嘗試PNGwriter!它逐個像素地寫入圖像和它們的RGB值。由於PNGwriter開始表格左上方的同時glReadPixels()從左下方,而像開始,你的代碼:

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。我也嘗試libgd,但它似乎只將一個圖像文件(在硬盤或內存中)轉換爲另一種格式的圖像。但我認爲它仍然有用,而您想將許多PNG文件轉換爲GIF格式以創建GIF動畫。

相關問題