Panel użytkownika
Nazwa użytkownika:
Hasło:
Nie masz jeszcze konta?

[WinAPI] Szybkie szukanie piksela o określonym kolorze...

Ostatnio zmodyfikowano 2011-08-30 01:13
Autor Wiadomość
Mrovqa
Temat założony przez niniejszego użytkownika
[WinAPI] Szybkie szukanie piksela o określonym kolorze...
» 2011-08-28 15:24:53
Witam!

Aplikacja ma znaleźć pixel o określonym kolorze z całego ekranu i wypisać współrzędne tego pixela.
Próbowałem z
HDC desk = GetDC( NULL );
 i później w pętelkach (zagnieżdżone w sobie)
GetPixel( desk, x, y ) == RGB( 204, 0, 0 )
... To jest strasznie wolne! Czekam i czekam, po kilkudziesięciu sekundach przeleciało jeden wiersz pixeli!
Jest jakieś szybkie rozwiązanie?

Pozdrawiam,
Mrowqa
P-40118
mati1qazxsw2
» 2011-08-28 16:45:55
Użyj wstawki ASM :D
P-40121
michalp
» 2011-08-28 17:10:57
Zwijanie pętli.
P-40123
yoogi
» 2011-08-28 17:20:02
Zrób screena, a potem potem za pomocą uchwytu na bitmapę poszukaj pixela który cię interesuję. Tu masz kod od screena:
C/C++
#include <windows.h>
#include <windowsx.h>

LRESULT CALLBACK WindowProcedure( HWND, UINT, WPARAM, LPARAM );
void CaptureScreen( HWND );
void OnPaint( HWND hwnd );

char szClassName[] = "Screenshot";

HBITMAP hBitmap = NULL;
HBITMAP a = NULL;

int WINAPI WinMain( HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil )
{
    HWND hwnd;
    MSG messages;
    WNDCLASSEX wincl;
    HDC dc;
   
    wincl.hInstance = hThisInstance;
    wincl.lpszClassName = szClassName;
    wincl.lpfnWndProc = WindowProcedure;
    wincl.style = CS_DBLCLKS;
    wincl.cbSize = sizeof( WNDCLASSEX );
    wincl.hIcon = LoadIcon( NULL, IDI_APPLICATION );
    wincl.hIconSm = LoadIcon( NULL, IDI_APPLICATION );
    wincl.hCursor = LoadCursor( NULL, IDC_ARROW );
    wincl.lpszMenuName = NULL;
    wincl.cbClsExtra = 0;
    wincl.cbWndExtra = 0;
    wincl.hbrBackground =( HBRUSH ) COLOR_BACKGROUND;
    if( !RegisterClassEx( & wincl ) ) return 0;
   
    hwnd = CreateWindowEx( 0, szClassName, "Screenshot", WS_POPUP, CW_USEDEFAULT, CW_USEDEFAULT, 400, 300, HWND_DESKTOP, NULL, hThisInstance, NULL );
    CaptureScreen( hwnd );
    ShowWindow( hwnd, SW_MAXIMIZE );
    while( GetMessage( & messages, NULL, 0, 0 ) )
    {
        TranslateMessage( & messages );
        DispatchMessage( & messages );
    }
   
    return messages.wParam;
}

LRESULT CALLBACK WindowProcedure( HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam )
{
    switch( message )
    {
    case WM_PAINT:
        HANDLE_WM_PAINT( hwnd, wParam, lParam, OnPaint );
        break;
    case WM_DESTROY:
        PostQuitMessage( 0 );
        break;
        default:
        return DefWindowProc( hwnd, message, wParam, lParam );
    }
    return 0;
   
}

void OnPaint( HWND hwnd )
{
    HDC hBitmapdc, hWindowdc;
    HBITMAP hOld;
    PAINTSTRUCT ps;
    RECT rc;
    int nWid, nHt;
   
    if( a )
    {
        hWindowdc = BeginPaint( hwnd, & ps );
        hWindowdc = GetDC( hwnd );
        hBitmapdc = CreateCompatibleDC( hWindowdc );
        hOld = SelectBitmap( hBitmapdc, a );
        GetClientRect( hwnd, & rc );
        nWid = GetSystemMetrics( SM_CXSCREEN );
        nHt = GetSystemMetrics( SM_CYSCREEN );
        StretchBlt( hWindowdc, 0, 0, rc.right, rc.bottom, hBitmapdc, 0, 0, nWid, nHt, SRCCOPY );
        DeleteDC( hBitmapdc );
        EndPaint( hwnd, & ps );
    }
}

void CaptureScreen( HWND hParent )
{
    HDC hDesktopdc, hBitmapdc;
    int nWid, nHt;
    HBITMAP hOriginal;
    hDesktopdc = GetWindowDC( HWND_DESKTOP );
    if( hDesktopdc )
    {
        nWid = GetSystemMetrics( SM_CXSCREEN );
        nHt = GetSystemMetrics( SM_CYSCREEN );
        hBitmap = CreateCompatibleBitmap( hDesktopdc, nWid, nHt );
        hBitmapdc = CreateCompatibleDC( hDesktopdc );
        hOriginal =( HBITMAP ) SelectBitmap( hBitmapdc, hBitmap );
        BitBlt( hBitmapdc, 0, 0, nWid, nHt, hDesktopdc, 0, 0, SRCCOPY );
        DeleteDC( hBitmapdc );
        ReleaseDC( HWND_DESKTOP, hDesktopdc );
        UpdateWindow( hParent );
        a = hBitmap;
    }
}
P-40124
Mrovqa
Temat założony przez niniejszego użytkownika
» 2011-08-29 14:50:53
Dzięki, sprawdzę to zaraz...
a jest jakaś w miarę szybka funkcja szukająca? Chodzi mi konkretnie o to, że program ciągle szuka piksela... tzn. robi screena, przeszukuje obraz w poszukiwaniu piksela, jak znajdzie to zwraca współrzędne piksela, a jak nie to od początku (robi screena itd). Chciałbym by to było szybkie... praktycznie natychmiastowo znajdowało to ;)

/edit:
to co mi wyszło działa straszliwie wolno oraz zżera dużo %CPU ;/
P-40171
DejaVu
» 2011-08-29 15:25:52
To spróbuj zrobić 5 pajacyków natychmiastowo :)
P-40175
Mrovqa
Temat założony przez niniejszego użytkownika
» 2011-08-29 15:27:46
@up
Mój program szuka kilka(naście) sekund zżerając na 1 wątek około 20% CPU... mam inny który to robi w czasie około sekundy ze zużyciem 0-2% CPU... (nie mój, w binarce)
P-40176
DejaVu
» 2011-08-29 15:36:16
3.1MB zajmuje bitmapa 32-bitowa o wymiarach 1024x768 - w tym jest 786K pikseli. Wszystkie musisz sprawdzić i szybciej jak liniowo ich nie przejdziesz. Co najwyżej możesz skopiować do ciągłego obszaru pamięci cały uzyskany zrzut ekranu i porównywać wartości pikseli do intów zapobiegając tym samym wywoływaniu 786K razy funkcji GetPixel, która jest tu wąskim gardłem (pomijając rozmiar bitmapy i liczbę iteracji).
P-40179
« 1 » 2
  Strona 1 z 2 Następna strona