Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

Récupération des pixels d'une fenêtre cachée

5 réponses
Avatar
sebcmoa
Bonjour,

Je vous expose mon probl=E8me :

- J'utilise la fonction glReadPixels sur une fen=EAtre invisible. Cela
me retourne bien les donn=E9es...mais probl=E8me connu...cette fonction
est bien trop lente.

- J'essaie donc de r=E9cup=E9rer les donn=E9es de la fen=EAtre (de son DC)
d'une mani=E8re plus rapide. J'ai besoin d'avoir la valeur RGBA de
chaque pixel de la fen=EAtre pour faire des traitements dessus par la
suite.

- J'ai d=E9j=E0 tent=E9 de cr=E9er une texture OPENGL et de r=E9cup=E9rer l=
es
donn=E9es comme cela mais les valeurs de hauteur et de largeur de ma
texture doivent =EAtre des puissances de deux et je ne connais pas par
avance la taille de ma fen=EAtre.

- Je me suis donc tourn=E9 vers l'API windows et getDIBits. getDIBits
n'est pas cens=E9 me retourner les valeurs de ALPHA mais un getDIBits +
un glReadPixels de la valeur ALPHA reste plus rapide qu'un
glReadPixels sur les donn=E9es RGBA.
J'ai donc tent=E9 le code suivant que j'ai trouv=E9 en fouillant la
toile :

[CODE]
HDC hDCMem =3D CreateCompatibleDC(s->native.window.hDC);
HBITMAP hBmp =3D NULL;
HGDIOBJ hOld;
HDC hDC;
LRESULT res;

RECT rect;
int temp,i,j;
unsigned long * temp_pix =3D pixels;

BITMAPINFO bitmap_info;

bitmap_info.bmiHeader.biSize =3D sizeof(BITMAPINFOHEADER);
bitmap_info.bmiHeader.biWidth =3D width;
bitmap_info.bmiHeader.biHeight =3D -(signed)height;
bitmap_info.bmiHeader.biPlanes =3D 1;
bitmap_info.bmiHeader.biBitCount =3D 32;
bitmap_info.bmiHeader.biCompression =3D BI_BITFIELDS;
bitmap_info.bmiHeader.biXPelsPerMeter =3D 0;
bitmap_info.bmiHeader.biYPelsPerMeter =3D 0;
bitmap_info.bmiHeader.biClrUsed =3D 0;
bitmap_info.bmiHeader.biClrImportant =3D 0;
GetWindowRect(s->native.window.hWND, & rect);

hBmp =3D CreateCompatibleBitmap(hDCMem,width,height);
hOld =3D SelectObject(hDCMem, hBmp);

GetDIBits(hDCMem,hBmp,0,height,NULL,&bitmap_info,DIB_RGB_COLORS);

res =3D SendMessage(s->native.window.hWND, WM_PRINT, (WPARAM)
hDCMem, PRF_CHILDREN | PRF_CLIENT);

res =3D GetDIBits(hDCMem,hBmp,
0,height,pixels,&bitmap_info,DIB_RGB_COLORS);

SelectObject(hDCMem, hOld);
DeleteObject(hDCMem);
[/CODE]

Mais je n'obtiens aucune donn=E9e...

Quelqu'un aurait-il une petite id=E9e de comment r=E9cup=E9rer les donn=E9e=
s
d'une fen=EAtre cach=E9e ou plut=F4t les pixels du DC associ=E9...) ?

Merci par avance.

5 réponses

Avatar
Christian ASTOR
wrote:

- Je me suis donc tourné vers l'API windows et getDIBits. getDIBits
n'est pas censé me retourner les valeurs de ALPHA mais un getDIBits +
un glReadPixels de la valeur ALPHA reste plus rapide qu'un
glReadPixels sur les données RGBA.
J'ai donc tenté le code suivant que j'ai trouvé en fouillant la
toile :



Hormis que ce n'est pas compilable, il y a des bugs comme
CreateCompatibleBitmap() qui ne doit pas se faire sur un Memory DC
Pour les fenêtres non visibles, PrintWindow() fonctionne plus souvent
que WM_PRINT*
Pour GetDIBits() et les DIB, voir les ex de la PSDK dans
SamplesMultimediaGdi (WinCap32, ...)
Avatar
sebcmoa
> Hormis que ce n'est pas compilable, il y a des bugs comme
CreateCompatibleBitmap() qui ne doit pas se faire sur un Memory DC
Pour les fenêtres non visibles, PrintWindow() fonctionne plus souvent
que WM_PRINT*
Pour GetDIBits() et les DIB, voir les ex de la PSDK dans
SamplesMultimediaGdi (WinCap32, ...)




Le "pas compilable", bien entendu pour pouvoir tester j'ai adapté le
code pour que cela marche...

Pour le "PrintWindow" j'ai un soucis car en ajoutant l'include
windows.h & en linkant avec user32.lib
cela ne passe pas ... j'ai même tenté avec winspool.h/lib...mais
toujours rien ça ne passe pas à la
compilation...d'où le SendMessage que j'ai laissé...

Par contre les GetDIBits je ne vois pas torp trop le soucis...
Avatar
sebcmoa
On 24 nov, 14:38, wrote:
> Hormis que ce n'est pas compilable, il y a des bugs comme
> CreateCompatibleBitmap() qui ne doit pas se faire sur un Memory DC
> Pour les fenêtres non visibles, PrintWindow() fonctionne plus souvent
> que WM_PRINT*
> Pour GetDIBits() et les DIB, voir les ex de la PSDK dans
> SamplesMultimediaGdi (WinCap32, ...)

Le "pas compilable", bien entendu pour pouvoir tester j'ai adapté le
code pour que cela marche...

Pour le "PrintWindow" j'ai un soucis car en ajoutant l'include
windows.h & en linkant avec user32.lib
cela ne passe pas ... j'ai même tenté avec winspool.h/lib...mais
toujours rien ça ne passe pas à la
compilation...d'où le SendMessage que j'ai laissé...

Par contre les GetDIBits je ne vois pas torp trop le soucis...



PrintWindow obtenu avec un GetProcAddress...ça ça passe mais toujours
que des pixels noirs après le GetDIBits...
Avatar
Christian ASTOR
wrote:

On 24 nov, 14:38, wrote:

Hormis que ce n'est pas compilable, il y a des bugs comme
CreateCompatibleBitmap() qui ne doit pas se faire sur un Memory DC
Pour les fenêtres non visibles, PrintWindow() fonctionne plus souvent
que WM_PRINT*
Pour GetDIBits() et les DIB, voir les ex de la PSDK dans
SamplesMultimediaGdi (WinCap32, ...)



Le "pas compilable", bien entendu pour pouvoir tester j'ai adapté le
code pour que cela marche...

Pour le "PrintWindow" j'ai un soucis car en ajoutant l'include
windows.h & en linkant avec user32.lib
cela ne passe pas ... j'ai même tenté avec winspool.h/lib...mais
toujours rien ça ne passe pas à la
compilation...d'où le SendMessage que j'ai laissé...

Par contre les GetDIBits je ne vois pas torp trop le soucis...




PrintWindow obtenu avec un GetProcAddress...ça ça passe mais toujours
que des pixels noirs après le GetDIBits...



PrintWindow() dépend de _WIN32_WINNT
Si je teste un DDB avec, par ex, la Calculatrice (sans tenir compte du
cas où elle est minimizée (SetParent(), ...)) :

HWND hWndDest = FindWindow(L"SciCalc", NULL);
RECT rect;
GetWindowRect(hWndDest, &rect);
int nWidth = rect.right - rect.left;
int nHeight = rect.bottom - rect.top;
HDC hScreenDC = GetDC(NULL);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, nWidth, nHeight);
HDC hDCMem = CreateCompatibleDC(hScreenDC);
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmap);
PrintWindow(hWndDest, hDCMem, 0);
// Test si hBitmap est OK en la copiant sur l'écran
BitBlt(hScreenDC, 0, 0, nWidth, nHeight, hDCMem, 0, 0, SRCCOPY);
// Releases...
SelectObject(hDCMem, hBitmapOld);
DeleteDC(hDCMem);
DeleteObject(hBitmap);
ReleaseDC(NULL, hScreenDC);
Avatar
sebcmoa
On 24 nov, 21:49, Christian ASTOR wrote:
wrote:
> On 24 nov, 14:38, wrote:

>>>Hormis que ce n'est pas compilable, il y a des bugs comme
>>>CreateCompatibleBitmap() qui ne doit pas se faire sur un Memory DC
>>>Pour les fenêtres non visibles, PrintWindow() fonctionne plus souven t
>>>que WM_PRINT*
>>>Pour GetDIBits() et les DIB, voir les ex de la PSDK dans
>>>SamplesMultimediaGdi (WinCap32, ...)

>>Le "pas compilable", bien entendu pour pouvoir tester j'ai adapté le
>>code pour que cela marche...

>>Pour le "PrintWindow" j'ai un soucis car en ajoutant l'include
>>windows.h & en linkant avec user32.lib
>>cela ne passe pas ... j'ai même tenté avec winspool.h/lib...mais
>>toujours rien ça ne passe pas à la
>>compilation...d'où le SendMessage que j'ai laissé...

>>Par contre les GetDIBits je ne vois pas torp trop le soucis...

> PrintWindow obtenu avec un GetProcAddress...ça ça passe mais toujou rs
> que des pixels noirs après le GetDIBits...

PrintWindow() dépend de _WIN32_WINNT
Si je teste un DDB avec, par ex, la Calculatrice (sans tenir compte du
cas où elle est minimizée (SetParent(), ...)) :

HWND hWndDest = FindWindow(L"SciCalc", NULL);
RECT rect;
GetWindowRect(hWndDest, &rect);
int nWidth = rect.right - rect.left;
int nHeight = rect.bottom - rect.top;
HDC hScreenDC = GetDC(NULL);
HBITMAP hBitmap = CreateCompatibleBitmap(hScreenDC, nWidth, nHeight);
HDC hDCMem = CreateCompatibleDC(hScreenDC);
HBITMAP hBitmapOld = (HBITMAP)SelectObject(hDCMem, hBitmap);
PrintWindow(hWndDest, hDCMem, 0);
// Test si hBitmap est OK en la copiant sur l'écran
BitBlt(hScreenDC, 0, 0, nWidth, nHeight, hDCMem, 0, 0, SRCCOPY);
// Releases...
SelectObject(hDCMem, hBitmapOld);
DeleteDC(hDCMem);
DeleteObject(hBitmap);
ReleaseDC(NULL, hScreenDC);





OK...m'ci...je vois où étaient mes soucis...mais bon cela n'a pas
résolu mon problème...la seule chose que j'ai réussi à récupére r pour
le moment c'est le bord de ma fenêtre cachée...mais pas le contenu...