AnusIsRael Temat założony przez niniejszego użytkownika |
Kolejność kolorów w pikselach, GDI32 » 2016-09-01 21:58:54 Witam, otóż ostatnio postanowiłem napisać program, który miałby kopiować obszar pikseli z ekranu do bufora a następnie go przetwarzać. Wygląda on następująco: #include "windows.h" #include "stdio.h" #include "cstdint"
#define X 138 #define Y 138 #define Size X*Y
#define StartX 892 #define StartY 530
uint8_t * pPixel;
uint8_t * GetSquare() { HDC CurrentWindow = GetDC( NULL ); HDC Temp = CreateCompatibleDC( CurrentWindow ); BITMAPINFO iBitmap; iBitmap.bmiHeader.biSize = sizeof( iBitmap.bmiHeader ); iBitmap.bmiHeader.biWidth = X; iBitmap.bmiHeader.biHeight = Y; iBitmap.bmiHeader.biPlanes = 1; iBitmap.bmiHeader.biBitCount = 24; iBitmap.bmiHeader.biCompression = BI_RGB; iBitmap.bmiHeader.biSizeImage = X * 3 * Y; iBitmap.bmiHeader.biClrUsed = 0; iBitmap.bmiHeader.biClrImportant = 0; HBITMAP hBitmap = CreateDIBSection( Temp, & iBitmap, DIB_RGB_COLORS,( void ** )( & pPixel ), NULL, 0 ); SelectObject( Temp, hBitmap ); BitBlt( Temp, 0, 0, X, Y, CurrentWindow, StartX, StartY, SRCCOPY ); return pPixel; }
int main( int argc, char ** argv ) { system( "PAUSE" ); uint8_t * temp = GetSquare(); for( int i = 0; i <( Size * 3 ); i += 3 ) { printf( "RED %u\n", temp[ i ] ); printf( "GREEN %u\n", temp[ i + 1 ] ); printf( "BLUE %u\n", temp[ i + 2 ] ); printf( "%u\n", i ); } system( "PAUSE" ); }
Cały problem polega na tym, że kolejność reprezentacji kolorów ulega zmianie co szerokość ramki (138 pikseli), czyli co 138*3 i. Reprezentacja zaczyna się od BGR (przesunięcie o 2 bajty), po czym przechodzi chyba przez każdą możliwą kombinacje (RGB, GBR, RBG, etc...) Wychodzi na to, że gubie gdzieś jeden bajt co wiersz, dlaczego? Używam GCC w wersji 5.1.0 (g++ -O3 -std=c++14 -o file.exe file.cpp -lgdi32) pod windowsem 10 pro x64 Log kompilacji jest czysty, tzn: żadnych błędów, uwag. Będę wdzięczny za każdą sugestie :) ~AIR |
|
pekfos |
» 2016-09-01 23:21:30 Linie są wyrównane do wielokrotności rozmiaru DWORD. |
|
AnusIsRael Temat założony przez niniejszego użytkownika |
» 2016-09-01 23:51:11 Zmieniłem BitCount na 32 więc jest wielokrotnością DWORD, tymczasem problem pozostaje. iBitmap.bmiHeader.biSize = sizeof( iBitmap.bmiHeader ) iBitmap.bmiHeader.biWidth = X; iBitmap.bmiHeader.biHeight = Y; iBitmap.bmiHeader.biPlanes = 1; iBitmap.bmiHeader.biBitCount = 32; iBitmap.bmiHeader.biCompression = BI_RGB; iBitmap.bmiHeader.biSizeImage = X * 4 * Y; iBitmap.bmiHeader.biClrUsed = 0; iBitmap.bmiHeader.biClrImportant = 0;
EDIT: Problem rozwiązany, okazuje się, że wartości podawane są domyślnie w BGR. Dzięki za pomoc :)! |
|
pekfos |
» 2016-09-02 00:08:18 Czy to zmienisz, czy nie, musisz zmodyfikować swoją pętlę w main(). |
|
AnusIsRael Temat założony przez niniejszego użytkownika |
» 2016-09-02 00:38:31 Tak zrobiłem :v |
|
Rashmistrz |
» 2016-09-02 18:16:54 Linie są wyrównane do wielokrotności rozmiaru DWORD. |
Zmieniłem BitCount na 32 więc jest wielokrotnością DWORD, tymczasem problem pozostaje. |
Emmmm... ale to linie mają być wyrównane, a nie piksele... Tak powiedział Pekfos. // (do adresu który jest wielokrotnością DWORD) // twój kod: for( int i = 0; i <( Size * 3 ); i += 3 ) { printf( "RED %u\n", temp[ i ] ); printf( "GREEN %u\n", temp[ i + 1 ] ); printf( "BLUE %u\n", temp[ i + 2 ] ); printf( "%u\n", i ); } Jak dobrze zrozumiałem to powinno być tak: Wypisujesz jedną linijkę, wyrównujesz zmienną indeksową do wielokrotności 4-rech i wypisujesz kolejną linijkę. Czynność powtarzaj do wypisania wszystkiego... czy jak tam wolisz. |
|
AnusIsRael Temat założony przez niniejszego użytkownika |
» 2016-09-04 00:49:46 Przecież napisałem, że zmieniłem pętle razem z headerem :v for( int i = 0; i <( Size * 4 ); i += 4 ) { printf( "RED %u\n", temp[ i ] ); printf( "GREEN %u\n", temp[ i + 1 ] ); printf( "BLUE %u\n", temp[ i + 2 ] ); printf( "%u\n", i ); }
Myślałem, że błąd występuje nadal, gdyż nie wiedziałem, że kolory zapisane są w BGRA a nie RGBA. |
|
« 1 » |