PDA

Visualizza la versione completa : [c] rilevare colore pixel !!


indovinello
09-10-2012, 15:58
ciao a tutti... volevo sapere se conoscete un modo per rilevare il colore di un pixel date le rispettive coordinate??
cercando su internet ho trovato il seguente codiche ...


#include <windows.h>
#include <string.h>
#include <stdio.h>
#include <stdlib.h>

int main()
{
POINT mouse; //definizione necessaria per il mouse
/*ho creato in paint 3 rettangoli pieni uno nero uno blu e uno verde*/
HWND hwnd = FindWindow(NULL,"Immagine - Paint");
SetForegroundWindow(hwnd);
Sleep(1000); //aspetto un po
HDC hdc = GetDC(hwnd);
GetCursorPos(&mouse);//posizione mouse
printf("pos x=%ld\ty=%ld\n",mouse.x,mouse.y);

COLORREF col = GetPixel(hwnd,mouse.x,mouse.y);

printf("rosso:%d\nverde:%d\nblu:%d\n",getRValue(col),GetGValue(col),GetBValue(col));
ReleaseDC(hwnd,hdc);

return 0;
}

problema... mi restituisce sempre 255 255 255 che il bianco... leggendo in giro ho visto che il problema dovuto al CLR_INVALID cioe il pixel che mi interessa fuori dalla regione di ritaglio corrente...

che vuole dire??? che la finesta dove il pixel che voglio non quella che gli passo io nella getDC???
come posso risolvere il problema??

MItaly
09-10-2012, 16:21
1. Le coordinate del DC non sono le coordinate-schermo, devi fare una conversione da coordinate-schermo a coordinate-client (ScreenToClient (http://msdn.microsoft.com/en-us/library/windows/desktop/dd162952%28v=vs.85%29.aspx));
2. Stai passando a GetPixel l'handle di finestra invece dell'handle al DC, ovviamente non pu funzionare.

Comunque se volessi fare una cosa del genere lascerei stare la ricerca della finestra specifica, crea un DC relativo all'area di tutti gli schermi (CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL)) e usa direttamente quello (e ti eviti anche la conversione di coordinate).

In ogni caso, se non hai mai fatto programmazione con WinAPI ti consiglio di leggerti prima un libro in proposito.

indovinello
09-10-2012, 16:38
ok grazie mille della risposta...
usando CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL)
ho risolto tutto...
un'ultima cosa... ho letto che cosa fa la funzione ma non sono sicuro di aver capito bene..
in pratica mi fornisce "l'indirizzo" del desktop vedendolo come una unica finestra...
giusto??

altro dubbio... nel codice devo inserire ReleaseDC() o diventa inutile?? e siccome devo fare un controllo periodico del pixel questa funzione mi intasa la memoria o la cpu?

MItaly
09-10-2012, 16:52
Originariamente inviato da indovinello
ok grazie mille della risposta...
usando CreateDC(TEXT("DISPLAY"),NULL,NULL,NULL)
ho risolto tutto...
un'ultima cosa... ho letto che cosa fa la funzione ma non sono sicuro di aver capito bene..
in pratica mi fornisce "l'indirizzo" del desktop vedendolo come una unica finestra...
giusto??
Ti fornisce un device context "complessivo" di tutti gli schermi. (un device context un'astrazione di dispositivo su cui si pu disegnare; per ulteriori informazioni a proposito, ti rimando alla documentazione (http://msdn.microsoft.com/en-us/library/windows/desktop/dd183553%28v=vs.85%29.aspx), o come detto prima, ad un libro di programmazione Win32)


altro dubbio... nel codice devo inserire ReleaseDC() o diventa inutile??
Devi usare DeleteDC, come spiegato nella documentazione:


When you no longer need the DC, call the DeleteDC function.
In generale,
GetDC->ReleaseDC
CreateDC->DeleteDC


e siccome devo fare un controllo periodico del pixel questa funzione mi intasa la memoria o la cpu?
Non particolarmente, magari evita di continuare a creare e cancellare il DC (crealo all'avvio del programma e eliminalo alla chiusura).

indovinello
10-10-2012, 12:34
ok grazie... ora ho risolto e funziona alla grande!!!

ultima cosa... se io volessi in un qualunque momento rilevare la pressione del tasto f come posso fare??

esempio


int main
{
int a,b,c,v;
char r,tyy;
//altre variabili

for()
{
//fa quello che deve fare
}

while (1==1)
{
//simulo pressione tasti
keybd_event('c', 0, 0, 0 );
keybd_event('c', 0, KEYEVENTF_KEYUP, 0 );
keybd_event('i', 0, 0, 0 );
keybd_event('i', 0, KEYEVENTF_KEYUP, 0 );
keybd_event('a', 0, 0, 0 );
keybd_event('a', 0, KEYEVENTF_KEYUP, 0 );
keybd_event('o', 0, 0, 0 );
keybd_event('o', 0, KEYEVENTF_KEYUP, 0 );

/*-----altri cicli vari-----*/
Sleep (2000); //aspetto 2 secondi
}

}

eseguendo questo codice a un certo punto voglio smettere e premo f e lui termina... so che per rilevare la pressione di un tasto devo usare GetAsyncKeyState(valore ascii tasto)
pero dove lo metto, all'interno di ogni ciclo??? puo essere che entri in conflitto con la keybd_event??

MItaly
10-10-2012, 13:18
Altro problema -> altro thread.
:ciauz:

Loading