GetPixel()

0

Witam!
Mam problem z pobraniem koloru danego piksela z ekranu. Chciałem użyć funkcji GetPixel(). Na msdn pisze, że jako pierwszy parametr przyjmuje "A handle to the device context". Nie wiem zupełnie co to jest i co dokładnie muszę podać funkcji jako pierwszy argument [???] . Prosiłbym o jakąś pomoc, najlepiej przydałby mi się króciutki przykład jak pobrać kolor piksela z monitora. Za wszelką pomoc będę wdzięczny.
Pozdrawiam

0

Handle - uchwyt
device - urzadzenie
context - kontekst
http://lublin.webd.pl/crayze/cpp-winapi/winapi3_5.html

0

Ok, wielkie dzięki za odpowiedź. Tylko jest taka sprawa, spróbowałem skompilować coś takiego:

#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
    HDC caly_pulpit = GetDC(0);
    GetPixel(caly_pulpit, 100, 100);  
    return 0;
}

I wywala mi błąd linkera:

undefined reference to `GetPixel@12'

Gdzie jest błąd?

0
radoslav006 napisał(a)

HDC caly_pulpit = GetDC(0);

W tym.Jako parametr uchwytu do okna podajesz 0,co kończy się jak to zwykle kończą null-pointery
Daawno się już WinAPI32 nie bawiłem,ale z tego co pamiętam,to albo createWindow,albo registerClass zwracają owo HWND.Musisz je zapamiętać,po czym wykorzystywać w takich sytuacjach jak twoja.

0

nie zlinkowałeś odpowiedniej bibliotekii, z msdn: "coredll.lib, Winmgr.lib"
zamiast 0 skorzystaj z GetDesktopWindow()

0

Dzięki wielkie!

Naprawdę bardzo mi pomogliście, teraz wszystko działa :) Naprawdę jestem bardzo wdzięczny, że tak szybko i sprawnie został rozwiązany mój problem.

Pozdrawiam

0

Hmm, dalej już sobie jakoś dam radę, ale mam takie pytanie. Czemu mi to nie chce działać? Tzn. kod się kompiluje, ale nie zmieniają mi się wartości które wypisuję w miarę poruszania myszką, nie wiem co jest tego przyczyną [???] Aha i jeszcze tak z ciekawości zapytam, jak tą liczbę która mi się wypisuje rozdzielić na 3 liczby, każda odpowiadająca za jeden kolor (red, green, blue)?

#include <iostream>
#include <windows.h>

using namespace std;

int main()
{
    HDC caly_pulpit=GetDC(GetDesktopWindow());
    POINT Point;
    while (true)
    {
        GetCursorPos(&Point);
        cout << GetPixel(caly_pulpit, Point.x, Point.y);
        system("cls");
    }
    return 0;
}
0

Bo czytasz pixel z położenia myszki, czyli cały czas odczytujesz kolor z kursora. jak będziesz czytał pixel x-1, lub y-1 to będzie czytało poprawnie.

0

Wycinek z mojego kodu. Wyswietla ci na biezaco polozenie kursora i kolor rozdzielony na R G B
Troche namieszane jest dalej w kodzie bo stopniowo dodawalem pewne rzeczy, ktore byly mi potrzebne akurat, ale najwazniejsze funkcje i dzialanie ogarniesz z tego. Xsleep to jest moja klasa bo w Qt nie ma lub nie moglem znalezc sleepa.

@up
W zasadzie to nie. Przy uzywaniu tej funkcji zauwazylem, ze jezeli kolor wyswietlany na biezaco sie niezmienia(255,255,255) to oznacza ze uchwyt okna podany jest nieprawidlowy. Jesli dawalem mu uchwyt do okna gry to z niego czytal prawidlowo, ale juz poza nim czyli pulpit, konsola wartosci byly zawsze takie same(255). Chociaz juz sam nie wiem, moze to i o kursor chodzi bo 255 to kolor bialy. Pewnie masz racje xD

inline short int Kolor(HDC GameWindow, POINT x, short int &G)
{
    short int R,B;
    COLORREF Kolor;
        Kolor=GetPixel(GameWindow,x.x,x.y);
        R=GetRValue(Kolor);
        G=GetGValue(Kolor);
        B=GetBValue(Kolor);
        cout << endl << "R: " << R << " G: " << G << " B: " << B;
        Xsleep::msleep(50);
    return R;
}

POINT MousePos(HDC GameWindow)
{
    POINT Koord;
    short int R,G,B;
    while(true)
    {
        GetCursorPos(&Koord);
        system("cls");
        cout << "X: " << Koord.x << " Y: " << Koord.y;
        R=Kolor(GameWindow,Koord,G);
        COLORREF Blue=GetPixel(GameWindow,Koord.x,Koord.y);
        B=GetBValue(Blue);
        Xsleep::msleep(50);
        if(GetAsyncKeyState(VK_MBUTTON) and R==255 and G!=255 or (GetAsyncKeyState(VK_MBUTTON) and B==255))
        {
            system("cls");
            cout << "Pobrano prawidlowo.";
            return Koord;
        }
        else if(GetAsyncKeyState(VK_MBUTTON) and R!=255)
        {
            cout << "\nBlad wartosc R musi byc rowna 255 - Kolor czerwony G i R jak najmniejsze..";
            Xsleep::msleep(2500);
        }
    }
}
0

Witajcie. Tez probuje zabawy z funckja getpixel ale bez zalinkowanych bibliotek wyskakuje mi blad jak u kolegi wyżej.
undefined reference to `GetPixel@12'
Gdy probuje linkowac biblioteki
user32.lib;
coredll.lib;

to mam blad albo ze nie moze znalezc pliku jak linkuje z rozszerzeniem.lib a jak dodam bez rozszerzenie to niby znajduje biblioteki ale mam blad :

sciezke do plikow tez podaje.

mingw32-g++.exe -LC:\Users\Karol\Desktop\kursor2\ -o bin\Debug\kursor2.exe obj\Debug\main.o -luser32 -lcoredll
C:\Users\Karol\Desktop\kursor2/user32.lib: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status

Mozecie pomoc? bo od 3 godzin walcze i nie mam juz pomyslow

0
Karol napisał(a):

Witajcie. Tez probuje zabawy z funckja getpixel ale bez zalinkowanych bibliotek wyskakuje mi blad jak u kolegi wyżej.
undefined reference to `GetPixel@12'
Gdy probuje linkowac biblioteki
user32.lib;
coredll.lib;

to mam blad albo ze nie moze znalezc pliku jak linkuje z rozszerzeniem.lib a jak dodam bez rozszerzenie to niby znajduje biblioteki ale mam blad :

sciezke do plikow tez podaje.

mingw32-g++.exe -LC:\Users\Karol\Desktop\kursor2\ -o bin\Debug\kursor2.exe obj\Debug\main.o -luser32 -lcoredll
C:\Users\Karol\Desktop\kursor2/user32.lib: file not recognized: File format not recognized
collect2.exe: error: ld returned 1 exit status

Mozecie pomoc? bo od 3 godzin walcze i nie mam juz pomyslow

Nie wiem co wy za szmelc używacie do linkowania...

GetPixel jest w gdi32.dll, jak i cała reszta do grafiki.

0

Nie denerwuj sie kolego. Zaraz sprawdze i zobaczę czy zadziałało.

0

Nie dziala. Dalej krzyczy ze nie zna typu plikow. Za to juz wiem jak zrobic zeby zadziałało.
Wystarcyz ze odpaliem nowy projekt jako Win32 GUI. Pomijam fakt ze getpixel pokazuje caly czas bialy kolor nawet na -1.
Ale ogolni program odpalil.
Moze mi ktos wytlumaczyc czemu odpalil na projkcie jako giu a na consolowym nie odpalil? mimo ze kod zrodlowy i tak jest skopiowany ze wczesniejszego projektu?

0
Karol napisał(a):

Nie dziala. Dalej krzyczy ze nie zna typu plikow. Za to juz wiem jak zrobic zeby zadziałało.
Wystarcyz ze odpaliem nowy projekt jako Win32 GUI. Pomijam fakt ze getpixel pokazuje caly czas bialy kolor nawet na -1.
Ale ogolni program odpalil.
Moze mi ktos wytlumaczyc czemu odpalil na projkcie jako giu a na consolowym nie odpalil? mimo ze kod zrodlowy i tak jest skopiowany ze wczesniejszego projektu?

Ty pracujesz w consoli... i chciałeś GetPixel odpalać?!
No to to przepłaszam, ale to już ponad moje kompetencje... :)

0

Nie pracuje, ucze się, staram się coś napisać. Jak Cie to tak przerasta, to zachowaj te swoje komentarze dla siebie. Bo po Twojej wypowiedzi dalej nie wiem czemu na zwyklej konsoli nie dziala a na konsoli z win32gui dziala.

0

Ty pracujesz w consoli... i chciałeś GetPixel odpalać?!

GetPixel to GetPixel. Jeśli dostanie prawidłowy device context to będzie działać. Konsola czy nie konsola - nie ma to nic do rzeczy.

0
Azarien napisał(a):

Ty pracujesz w consoli... i chciałeś GetPixel odpalać?!

GetPixel to GetPixel. Jeśli dostanie prawidłowy device context to będzie działać. Konsola czy nie konsola - nie ma to nic do rzeczy.

Naprawdę? No to gratuluję.. kompetencji. :)

0

Gdy probuje linkowac biblioteki
user32.lib;
coredll.lib;

W MinGW pliki .lib? Do bibliotek dodaj gdi32 i załącz <windows.h>.

0

Twoja rada byla pomocna. Tzn windows.h juz mialem. Teraz pytanie kolejne. Na windowsie 7 getpixel nie zabardzo dziala. Tzn raz dziala dobrze, a zaraz wraca wartosci jakby od czasu odpelanie programu. Jakby obraz okna gry mu sie zwieszal a nie byl rzeczywisty. Na 10 program dziala jak powinien, czyta kazdy kolor pixela dobrze od razu po zmianie jego koloru. Jest na to jakis sposob? czy po prostu ta funkcja na windows 7 nie dziala poprawnie?

0

Pokaż kod, bo tak to ciężko coś sensownego powiedzieć.

0
#include <tchar.h>
#include <windows.h>
#include <vector>
#include <iostream>
#include "mouseandkeyboard.h"
#include <winuser.h>
#include <wingdi.h>


using namespace std;
int main()

{
   HWND hwnd;

   POINT rod;
   POINT kur;
   short int R,G,B;

   cout << "Choose Window (SHIFT). ";
   while (1)
   {
       if (GetKeyState(VK_SHIFT) < 0)
       {
           hwnd = GetForegroundWindow();
           cout << "DONE!" << endl;
           break;
       }
       Sleep(100);
   }

   Sleep(150);



   Sleep(150);
   while (1)
   {

       HDC lol=GetDC(hwnd);
          rod = getCurrentPos(hwnd);


       unsigned int p=GetPixel(lol,rod.x,rod.y);
       unsigned int k=GetPixel(lol,1239,85);
    
       cout<<"ROD"<<endl;
       cout<<"x  "<<rod.x<<"y  "<<rod.y<<endl;
       cout<<p<<endl;
       R=GetRValue(p);
       G=GetGValue(p);
       B=GetBValue(p);
       cout  << "R: " << R << " G: " << G << " B: " << B<<endl;
       cout<<"......................"<<endl;

       cout<<"pixel"<<endl;
        cout<<k<<endl;
       R=GetRValue(k);
       G=GetGValue(k);
       B=GetBValue(k);
       cout  << "R: " << R << " G: " << G << " B: " << B<<endl;
       cout<<"......................"<<endl;

 
     system("cls");
     ReleaseDC( hwnd, lol );
        if(k!=16736370)
       {
           Beep(523,100);

       }
       Sleep(1000);
   }
   return 0;
}
```c++
0

Nie do konca mi to wyszlo. Dobra, zaraz sie zarenestruje. Bo nawet edytowac nie moge. Ogolnie teraz bedzie CI pokazywalo dwa pixele. Staly i z cursora. No i ogolnie to dziala na roznych ogienkach np na www jak masz rgb do wyboru, to pokazuje idealnie. Ale juz w grze stale rzeczy ktore sie nie mzieniaja pokazuje ok, ale jak juz kolor w danum miejscu sie zmieni, to on dalej widzi wczesnijeszy kolor w tym miejscu.

0

No i dziala to dobrze na windows 10. Takie cyrki o ktorych mowie pojawiaja sie na windows 7. ( to ja karol)
Rownież działa to dobrze, gdy zamiast okna hwnd, wpiszemy mu caly ekran czyli NULL. W przypadku hwnd, program jakoś sie gubi., jakby nie odświeżał okna.

Tutaj podaje jeszcze raz kod, bo tamten chcialem na szybko wyczyscic zebyś mial mniej syfu do pominiecia i Ci nie zadziala. Ten jest prosty. Najpierw wczytuje okno programu a pozniej pokazuje:
Point kursora
kolor
kolor RGB

Sprobuj jak to działą na stronach np takich ktore maja zmienne grafiki, albo jakiejs grze gdzie np odnawia sie zycie. jak wyzej. Na 10 dziala idealnie a na 7 krzaczy.

#include <tchar.h>
#include <windows.h>
#include <vector>
#include <iostream>
#include "mouseandkeyboard.h"
#include <winuser.h>
#include <wingdi.h>


using namespace std;
int main()

{
    HWND hwnd;

    POINT rod;
    POINT kur;
    short int R,G,B;

    cout << "Choose Window (SHIFT). ";
    while (1)
    {
        if (GetKeyState(VK_SHIFT) < 0)
        {
            hwnd = GetForegroundWindow();
            cout << "DONE!" << endl;
            break;
        }
        Sleep(100);
    }

    Sleep(150);


    Sleep(150);
    while (1)
    {

        HDC lol=GetDC(hwnd);

           rod = getCurrentPos(hwnd);
      
        cout<<"Kolor kursor"<<endl;
        cout<<"x  "<<rod.x<<"y  "<<rod.y<<endl;
        cout<<p<<endl;
        R=GetRValue(p);
        G=GetGValue(p);
        B=GetBValue(p);
        cout  << "R: " << R << " G: " << G << " B: " << B<<endl;
        cout<<"......................"<<endl;
        Sleep(2000);

      system("cls");
      ReleaseDC( hwnd, lol );
   
    }
    return 0;
}
0

Sprawdziłem ten Twój kod. U mnie, na W7, GetPixel zwracała tylko biały kolor, niezależnie od tego, co było pod kursorem. Dopiero jak dałem: HDC lol = GetDC(0);, wtedy dopiero zacząłem dostawać poprawne kolory, włącznie z oknami gdzie są animacje.

0

Tak wiem ze przy 0 zbiera wartosci dobrze, ale tutaj jest okno danej gry po to, zeby zbieralo wartosci po zminimalizowaniu gry. 0 zbiera wartosci tylko wtedy gdy jest okno na wierzchu. A jak zadeklarujesz hwnd = GetForegroundWindow(); a pozniej podepniesz hwnd do HDC lol=GetDC(hwnd); to zbiera pixele nawet przy zminimalizowanym oknie. Jest tylko problem taki, ze nie dziala to na W7. Wartosci biale o ktorych mowisz, zwraca wtedy kiedy jestes poza zdeklarowanyn oknem przez shift. Czyli no otwierasz przegladarke, odpalasz program, klikasz na przegladarke zeby byla glownym oknem i wtedy klikasz shift. I program wie, ze ma zbierac dane z przegladarki w tym przypadku pixele. Jak wyjedizesz kursorem poza okno przegladarki to bedize dawalo tylko bialy kolor. Ogolnie no ten skrypt dziala na win7 tylko sie wiesza.. Sprobuj odpalic ten moj skrypt z uprawmieniami administratora. Zaraz zobacze jeszcze jak to dziala na xp.

0

Wartosci biale o ktorych mowisz, zwraca wtedy kiedy jestes poza zdeklarowanyn oknem przez shift.

No właśnie nie, funkcja zwracała biały wszędzie, nawet jak kursor był nad oknem z uchwytu hwnd. Przyznam, że trochę mnie to zdziwiło, ale zrobiłem inaczej: stworzyłem bitmapę, do której kopiuje zawartość okna, i dopiero z tej bitmapy pobieram kolor. Takie rozwiązanie działa (oczywiście nie przy zminimalizowanym oknie).

0

A przy zaslonientym oknie bedzie dzialalo na bitmapie? np jakbys chcial czytac pixele z gry, ktora jest przeslonieta przegladarka? ( bo pixel wlasnie tak dziala, bo juz testowalemna win 10, an xp dziala dobrze poki nie jest niczym przesloniete, tak jak przy wartosci 0 czy tam NULL a na 7 krzaczy tak czy inaczej.).

0

Przy częściowym lub pełnym zasłonięciu zwraca poprawne kolory, więc wygląda, że działa. W XP ma prawo nie działać, bo od Visty zmieniono sposób rysowania okien - w XP okna rysowane są bezpośrednio w buforze ekranu, więc jeśli jakaś część okna jest przesłonięta przez inne okno, to ta część niewidoczna nie jest po prostu rysowana i nie ma z czego wyciągać kolorów. W Viście i wyżej okna rysowane są w całości do buforów, które kopiowane są później przez managera okien do bufora ekranu. Czyli dostęp do części przysłoniętej jest możliwy (no i u mnie jest).

0

Ok, teraz zasadnicze pytanie. Jak? Czy mógłbyś i dlaczego nie? :P

0
	HWND hwnd;
	POINT kur;
	short int R,G,B;

	std::cout << "Choose Window (SHIFT). ";
	while (1)
	{
		if (GetKeyState(VK_SHIFT) < 0)
		{
			hwnd = GetForegroundWindow();
			std::cout << "DONE!" << std::endl;
			break;
		}
		Sleep(100);
	}
 
	HDC hdc1 = GetDC(hwnd);
	HDC hdc2 = CreateCompatibleDC(hdc1);
	HBITMAP bmp = CreateCompatibleBitmap(hdc1, 1, 1);
	bmp = (HBITMAP) SelectObject(hdc2, bmp);

	while (1) 
	{ 
		GetCursorPos(&kur);
		ScreenToClient(hwnd, &kur);
		
		BitBlt(hdc2, 0, 0, 1, 1, hdc1, kur.x, kur.y, SRCCOPY);

		COLORREF p = GetPixel(hdc2, 0, 0);
				
		std::cout << "x  " << kur.x << "y  " << kur.y << '\n';
		
		R=GetRValue(p);
		G=GetGValue(p);
		B=GetBValue(p);
		
		std::cout  << "R: " << R << " G: " << G << " B: " << B << '\n';
		std::cout << "......................" << '\n';
		
		Sleep(1000);
	}
	
	bmp = (HBITMAP) SelectObject(hdc2, bmp);
	DeleteObject(bmp);
	DeleteDC(hdc2);
	ReleaseDC( hwnd, hdc1 );

1 użytkowników online, w tym zalogowanych: 0, gości: 1