Pixel farbe suchen[Pixelsearch]



  • hmmm.... und was wäre dein vorschlag, wie ich den variablen die werte richtig zuweisen könnte?

    übrigens sollte der teil, der im header übergangen wird der alpha teil sein.... für mich ist das aber nicht interressant^^



  • hat absolut keiner eine Idee?



  • // biBitCount = 32;
    for (int a=0; a<(dx*dy); a++)
    {
    	if (*(COLORREF*)memory[a] == RGB(suchende r,g,b))
    	{
    		// gefunden
    	}
    }
    


  • hast du das bitmap schon als datei gespeichert ung geguckt ob überhaupt etwas drin ist ?



  • @sapero
    Hmmm immer wenn ich etwas zwischen den Mengenklammern angebe (also die if abfrage gemacht wird) kommt die nachricht, dass mein compiledes script einen Fehler festgestellt hätte und ob dieser an microsoft gesendet werden solle O.o liegt das an Dev-C++? Compiler macht jedenfalls keine Zicken..
    @tipp
    .... ja, es ist was drin, aber es endsteht nur eine farbenfrohe bildschirmdiagonale 😉
    hier der Code zum prüfen:

    #include <windows.h>
    #include <iostream>
    
    using namespace std;
    
    int main()
    {
        //GetWindowRect(hwnd, &rect);
    
        Sleep(1000);
        int x=1, y=1, i;
        short rot, gruen, blau;
    
        HDC Bildschirm;
    
    	Bildschirm = CreateDC("DISPLAY",NULL,NULL,NULL); 
    	HWND hwnd = GetDesktopWindow();
    
    	if(!IsWindow(hwnd)) return 1;
    
    	RECT rect;
        GetWindowRect(hwnd, &rect);
        size_t dx = rect.right - rect.left;
        size_t dy = rect.bottom - rect.top;
    
               BITMAPINFO info;
               info.bmiHeader.biSize          = sizeof(BITMAPINFOHEADER);
               info.bmiHeader.biWidth         = dx;
               info.bmiHeader.biHeight        = dy;
               info.bmiHeader.biPlanes        = 1;
               info.bmiHeader.biBitCount      = 32;
               info.bmiHeader.biCompression   = BI_RGB;
               info.bmiHeader.biSizeImage     = 0;
               info.bmiHeader.biXPelsPerMeter = 0;
               info.bmiHeader.biYPelsPerMeter = 0;
               info.bmiHeader.biClrUsed       = 0;
               info.bmiHeader.biClrImportant  = 0;
    
                HBITMAP bitmap = 0;
                BYTE*   memory = 0;
    
                HDC device = GetDC(hwnd);
                bitmap = CreateDIBSection(device, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
                ReleaseDC(hwnd, device);
                if(!bitmap || !memory) return 1;
    
                HDC winDC = GetWindowDC(hwnd);
                HDC memDC = CreateCompatibleDC(winDC);
                SelectObject(memDC, bitmap);
                BitBlt(memDC, 0, 0, dx, dy, winDC, 0, 0, SRCCOPY);
                DeleteDC(memDC);
                ReleaseDC(hwnd, winDC);
    
            int tbytes = dx * dy * info.bmiHeader.biBitCount / 8;
           /*
            // biBitCount = 32;
            for (i=0; i<(dx*dy); i++)
            {
                if (*(COLORREF*)memory[i] == RGB(255,255,0))
                {
                // gefunden
                           x= i*8/info.bmiHeader.biBitCount/dy;
                           y= i*8/info.bmiHeader.biBitCount/dx;
                           SetPixel(Bildschirm, x, y, 0x000000)
                }
            }*/
    
            for(i = 0; i < tbytes; ++i)
            {
            rot=memory[++i]; //rot
            gruen=memory[++i]; //grün
            blau=memory[++i]; //blau
            x= i*8/info.bmiHeader.biBitCount/dy;
            y= i*8/info.bmiHeader.biBitCount/dx;
            SetPixel(Bildschirm, x, y, RGB(rot, gruen, blau));
            }
    
            DeleteObject(bitmap);
            bitmap = 0;
            memory = 0;
    
            //i= 1280*1024*32/8
            x= i*8/info.bmiHeader.biBitCount/dy;
            y= i*8/info.bmiHeader.biBitCount/dx;	
    
    //system("Pause");
    }
    


  • rot=memory[++i]; //rot 
    gruen=memory[++i]; //grün 
    blau=memory[++i]; //blau
    

    Das ist falsch:
    1. zuerst ist blau, grün, rot, und dann alpha/unused.
    2. teil = memory[++i] // ein Byte ist weg (memory[0])
    Ich habe immer definiert mein Zeiger als RGBQUAD* für 32-bit DIB's:

    RGBQUAD *memory;
    CreateDIBSection(..., (void**)&memory);
    

    RGBQUAD ist das selbe wie COLORREF, nur die einzelne Bytes haben Namen.



  • 1. zuerst ist blau, grün, rot

    danke 😉 hab vergessen das es BGR statt RGB ist..

    2. teil = memory[++i] // ein Byte ist weg (memory[0])

    memory[0]=Alpha Kanal
    memory[1]=Blau Kanal
    memory[2]=Grün Kanal
    memory[3]=Rot Kanal

    RGBQUAD ist das selbe wie COLORREF, nur die einzelne Bytes haben Namen

    und welchen vorteil/nachteil hat das für mich? 🙂

    man kommt in die schleife, i ist am anfang 0, wird auf 1 gesetzt und dann der memory[1] wert in der variable blau gespeichert.
    Am header wird dann immer der Alpha kanal übergangen....
    Allerdings stimmt meine rückrechnung auch nicht... Es ist jedesmal so, dass ich wenn ich x berechne, y meine desktophöhe sein müsste und wenn ich y berechne müsste x meine desktopweite sein....
    Die rückrechnung von x und y ist also falsch, ich weiß aber leider nicht, wie ich es sonst umsetzen kann....
    Hat wer von euch schonmal ein erfolgreiches script zum bitmap speichern oder durchsuchen gemacht?



  • Zuerst sorry für die inkomplete COLORREF = RGBQUAD, da R und B sind vertauscht. Hier ist die Belohnung:

    int main() 
    {
    	int x=1, y=1, i; 
    
    	int dx = GetSystemMetrics(SM_CXSCREEN);
    	int dy = GetSystemMetrics(SM_CYSCREEN);
    
    	BITMAPINFO info = {0};
    	info.bmiHeader.biSize     = sizeof(BITMAPINFOHEADER);
    	info.bmiHeader.biWidth    = dx;
    	info.bmiHeader.biHeight   = dy;
    	info.bmiHeader.biPlanes   = 1;
    	info.bmiHeader.biBitCount = 32; // 32:RGBQUAD; 24:RGBTRIPLE
    
    	HBITMAP bitmap;
    	RGBQUAD* memory;
    	HDC hdcDesktop = GetDC(0);
    	bitmap         = CreateDIBSection(hdcDesktop, &info, DIB_RGB_COLORS, (void**)&memory, 0, 0);
    	if(!bitmap || !memory) return ReleaseDC(0, hdcDesktop);
    
    	HDC hdcMemory  = CreateCompatibleDC(hdcDesktop);
    	HGDIOBJ oldbitmap = SelectObject(hdcMemory, bitmap);
    	BitBlt(hdcMemory, 0, 0, dx, dy, hdcDesktop, 0, 0, SRCCOPY);
    	// test
    	{
    		SetPixel(hdcMemory, 133, 144, RGB(255,255,1));
    	}
    	SelectObject(hdcMemory, oldbitmap);
    	DeleteDC(hdcMemory);
    	//ReleaseDC(0, hdcDesktop); später
    
    	int tbytes = dx * dy; 
    
    	// biBitCount = 32; 
    	for (i=0; i<tbytes; i++) 
    	{ 
    		RGBQUAD *p = &memory[i];
    		if (RGB(p->rgbRed, p->rgbGreen, p->rgbBlue) == RGB(255,255,1))
    		{ 
    			y = i / dx;
    			x = i % dx;
    			y = dy - y - 1; // nur wenn info.bmiHeader.biHeight ist positiv
    
    			Ellipse(hdcDesktop, x-32, y-32, x+32, y+32);
    			TCHAR info[64];
    			_stprintf(info, TEXT("gefunden at %dx%d"), x, y);
    			MessageBox(0, info, 0, 0);
    			break;
    		} 
    	}
    
    	DeleteObject(bitmap);
    	ReleaseDC(0, hdcDesktop);
    
    	return 0;
    }
    


  • danke 😃

    hat mir sehr geholfen 🙂



  • Hmm.... ich habe das gefühl, dass beim häufigerem aufrufen ein GDI lag endsteht, da die cpu lastung zwar extrem niedrig ist, der ganze pc jedoch anfängt zu hacken/laggen was extremer wird, je länger ich das Programm laufen lasse...

    Ich habe also den verdacht, dass die bitmap nicht richtig gelöscht/released wird...

    habe schon einiges Probiert um dieses Problem zu beheben, komme aber zu keiner wirksamen lösung...
    Tut mir leid, das ich euch immernoch damit belästige^^



  • GDI Leaks kannst du einfach mit dem Task Manager aufspüren. Da kannst du in den Optionen die eingeblendeten Spalten einstellen, u.a. auch GDI Handles.


Anmelden zum Antworten