2011-05-19 71 views
8

我想獲得屏幕或窗口的屏幕截圖。我嘗試使用從X11 功能,它工作正常。問題是從XImage獲取像素需要很多時間。 比我試圖尋找一些如何使用OpenGL做到這一點的答案。這裏就是我的了:截圖使用openGL和/或X11

#include <stdlib.h> 
#include <stdio.h> 
#include <cstdio> 
#include <GL/glut.h> 
#include <GL/gl.h> 
#include <GL/glx.h> 
#include <X11/Xlib.h> 


int main(int argc, char **argv) 
{ 

int width=1200; 
int height=800; 
//_____________________________---- 
Display *dpy; 
    Window root; 
    GLint att[] = { GLX_RGBA, GLX_DEPTH_SIZE, 24, GLX_DOUBLEBUFFER, None }; 
    XVisualInfo *vi; 
    GLXContext glc; 

    dpy = XOpenDisplay(NULL); 

    if (!dpy) { 
    printf("\n\tcannot connect to X server\n\n"); 
    exit(0); 
    } 

    root = DefaultRootWindow(dpy); 
    vi = glXChooseVisual(dpy, 0, att); 

    if (!vi) { 
    printf("\n\tno appropriate visual found\n\n"); 
    exit(0); 
    } 

glXMakeCurrent(dpy, root, glc); 
    glc = glXCreateContext(dpy, vi, NULL, GL_TRUE); 


    printf("vendor: %s\n", (const char*)glGetString(GL_VENDOR)); 

//____________________________________________ 
glXMakeCurrent(dpy, root, glc); 

glEnable(GL_DEPTH_TEST); 
GLubyte* pixelBuffer = new GLubyte[sizeof(GLubyte)*width*height*3*3]; 

glReadBuffer(GL_FRONT); 

GLint ReadBuffer; 
glGetIntegerv(GL_READ_BUFFER,&ReadBuffer); 
glPixelStorei(GL_READ_BUFFER,GL_RGB); 

GLint PackAlignment; 
glGetIntegerv(GL_PACK_ALIGNMENT,&PackAlignment); 
glPixelStorei(GL_PACK_ALIGNMENT,1); 

glReadPixels(0, 0, width, height, GL_RGB, GL_UNSIGNED_INT, pixelBuffer); 

int i; 

for (i=0;i<100;i++) printf("%u\n",((unsigned int *)pixelBuffer)[i]); 



return 0; 
} 

當我運行它,它會返回一個錯誤:失敗請求的 X錯誤:BadAccess(嘗試訪問私有資源被拒絕) 失敗請求的主要操作碼:199() 失敗請求的次操作碼:26 串行失敗請求的數目:在輸出流20 當前序列號:20

如果我評論的符合glXMakeCurrent(DPY,根,GLC); glc = glXCreateContext(dpy,vi,NULL,GL_TRUE);它不返回任何錯誤,但所有像素都爲0.

我該如何解決這個問題?我是新來的OpenGL,也許我錯過了重要的東西在這裏。也許另一種從屏幕或特定窗口獲取像素的方式存在?

+0

是什麼讓你的事情,使用GL將使它更快嗎?它應該是一樣的。 – 2011-05-19 19:02:11

+0

需要多少時間?是否涉及網絡傳輸?你只是在終端觀看標準輸出嗎?嘗試重定向到一個文件並使用'time'命令。將字符打印到終端使用的是同一臺X服務器,這些服務器拼命嘗試複製圖像並通過協議進行編組。海森堡可以申請;您的檢測技術可能會扭曲您尋求的信息。 – 2011-07-17 10:44:23

回答

7

我不認爲你在做什麼是可能的。你不能使用OpenGL從你不擁有的窗口讀取像素,而這些可能甚至不使用OpenGL。你需要堅持X11。

如果您有​​,您可以從ximage->data獲取原始像素。只要確保你以正確的格式閱讀它。

http://tronche.com/gui/x/xlib/graphics/images.html

+0

感謝您的回答。但是可以加快速度嗎?我不認爲XImage的像素是由ximage-> data線性表示的。我認爲像素是由分散在多個字節中的多個比特組成的,因此您需要很多位操作才能獲得像素值。我使用XGetPixel函數和XYPixmap,image = XGetImage(dis,DefaultRootWindow(dis),0,0,width,height,AllPlanes,XYPixmap);.也許我shodld使用不同的Pixmap,如ZPixmap?我必須在幾毫秒內獲得像素值,但獲取所有像素有時需要一秒。有沒有人有什麼建議? – 2011-05-19 20:00:37

+1

使用XShmGetImage()更快的方法。有關示例,請參見[link](http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c)中的代碼 – Christian 2012-08-19 07:40:34