2011-05-19 14 views
8

Ekranın veya pencerenin ekran görüntüsünü almaya çalışıyorum. X11 işlevlerini kullanmayı denedim ve iyi çalışıyor. Sorun şu ki XImage'dan piksel almak çok zaman alıyor. OpenGL kullanarak nasıl yapılacağına dair bazı cevaplar aramaya çalıştım. İşte ben bu var: Başarısız olan isteği X Hatası: BadAccess (özel kaynak yalanladı erişmeyi deneyin) Başarısız olan isteği Başlıca işlemkodu i programı çalıştırdığınızdaekran görüntüsü openGL ve/veya X11 kullanarak

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

Hata döndürürse 199() başarısız olan isteği Minör işlem kodu: başarısız isteğe 26 seri numarası: çıkış akımına 20 Mevcut seri numarası: 20

i glXMakeCurrent (dpy, kök, GLC) ile hat açıklama ise; önce glc = glXCreateContext (dpy, vi, NULL, GL_TRUE); hiçbir hata döndürmez, ancak tüm pikseller 0'dır.

Bu sorunu nasıl giderim? Ben openGL için yeni ve belki burada önemli bir şey eksik. Belki de ekrandan veya belirli bir pencereden piksel almanın başka bir yolu var mı?

+0

Uzantısı sorgulanıyor? Aynı olmalı. –

+0

Ne kadar zaman alıyor? Ağ iletimi var mı? Bir terminalde stdout'u mı görüntülüyorsunuz? Bir dosyaya yönlendirmeyi deneyin ve 'time' komutunu kullanın. Karakterleri terminale yazdırmak, çaresizce bir görüntüyü kopyalamaya çalışan bir protokolü kullanır ve bir protokolün üzerine yerleştirir. Heisenberg başvurabilir; muayene tekniğiniz, aradığınız bilgileri bozabilir. –

cevap

7

Yapmaya çalıştığınız şeyin mümkün olduğunu düşünmüyorum. Sahip olmadığınız pencereden pikselleri okumak için OpenGL'yi kullanamazsınız ve muhtemelen OpenGL'yi bile kullanamazsınız. X11'e bağlı kalmalısın.

XImage varsa, ximage->data'dan ham piksel elde edebilirsiniz. Sadece doğru biçimde okuduğunuzdan emin olun.

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

+0

Cevabınız için teşekkürler. Ancak hızlandırmak mümkün mü? XImage piksellerinin ximage-> verileriyle doğrusal olarak sunulduğunu düşünmüyorum. Piksellerin, birden çok bayt arasında dağılmış birden çok bitden oluştuğunu düşünüyorum. Bu nedenle piksel değerlerini elde etmek için çok fazla sayıda işlem yapmanız gerekir. XGetPixel işlevini ve XYPixmap, image = XGetImage (dis, DefaultRootWindow (dis), 0, 0, width, height, AllPlanes, XYPixmap) kullanıyorum. Belki de ZPixmap gibi farklı bir Pixmap kullanıyorum? Milisaniye cinsinden piksel değerleri elde etmek zorundayım, ancak tüm pikselleri elde etmek bazen bir saniyeye kadar sürüyor. Herhangi bir öneri var mı? –

+1

Daha hızlı bir yöntem için XShmGetImage() öğesini kullanın. Bir örnek için [link] 'deki kodu inceleyin (http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c) – Christian

4

Sen XShmGetImage kullanabilirsiniz ama emin MİT-SHM uzantısı kullanılabilir hale getirmek için, öncelikle X11 sunucunun uzantıları sorgulamak zorundayız. Bunun için paylaşılan bir bellek bölümünün nasıl kurulacağını ve kullanılacağını da bilmeniz gerekir.

http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l224

görüntü alma: GL kullanarak daha hızlı yapacak Eğer şeyi yapar ne

http://git.videolan.org/?p=ffmpeg.git;a=blob;f=libavdevice/x11grab.c#l537