Pixelsuche, TBitmap mit Scanline



  • ja der BitBlt Teil ist ja grad der wichtige Teil. BitBlt kopiert die Bilddaten von der Quelle zum Ziel.

    greetz KN4CK3R



  • DWORD WINAPI ScanFunc( LPVOID lpParam )
    {
       while(1)
       {
    	  if(scanthread==true)
    	  {
    	   Graphics::TBitmap *bmp = new Graphics::TBitmap();
    		dc = GetDC(NULL);
    		hBitmap = CreateCompatibleBitmap(dc, iSizeW, iSizeH);
    	 bmp->Height=iSizeH;
    	 bmp->Width=iSizeW;
    	 bmp->PixelFormat=pf24bit;
    	 bmp->Handle=hBitmap;
    	 cdc = GetWindowDC(0);
    	 BitBlt(bmp->Canvas->Handle, 0, 0,
    		   bmp->Width,  bmp->Height,
    		   cdc, 0, 0,
    		   SRCCOPY);
    
    	   for(scanx=0; scanx < bmp->Width; scanx++)
    		{
    		 ypix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scany]);
    		if(ypix->rgbtBlue == 191 && ypix->rgbtGreen==89 && ypix->rgbtRed ==255)
    			 {
    				MessageBox(0,"Gefunden","test1",MB_OK);
    			 }
    		for(scany=0; scany<bmp->Height; scany++)
    			{
    
    			}
    		}
    		ReleaseDC(0,dc);
    		ReleaseDC(0,cdc);
    		delete bmp;
    	  }
    	  Sleep(10);
       }
    }
    

    Wenn ich es richtig verstanden hab, dann muss es so gehen oder?
    Das Problem ist, ich kriege beim starten des Threads wieder die Fehlermeldung. Und kann deshalb nicht testen. Aber wieso kommt der Fehler wenn sich diesmal alles normal abläuft?



  • Debugger oder den Teil erstmal auskommentieren und schauen ob dein Screenshot jetzt stimmt.

    greetz KN4CK3R



  • Der Fehler wird durch GetDC(0) erzeugt.
    Wie soll ich es ohne GetDC(0) testen?

    EDIT: Einmal hat es geklappt. Hab sogar dann die bmp auf der Image gesehn aber, dann kam gleich eine Fehlemeldung "EOutOfResources... "falsche parameter".



  • du willst doch bloß meinen Code sehen 😉

    Graphics::TBitmap *s = new Graphics::TBitmap();
    TCanvas *canvas = new TCanvas();
    canvas->Handle = GetWindowDC(GetDesktopWindow());
    
    TRect source;
    GetWindowRect(GetDesktopWindow(),(LPRECT)&source);
    s->Width = source.Right;
    s->Height = source.Bottom;
    s->Canvas->CopyRect(s->Canvas->ClipRect,canvas,source);
    
    //mach was mit s
    
    s->FreeImage();
    delete s;
    

    greetz KN4CK3R



  • KN4CK3R schrieb:

    du willst doch bloß meinen Code sehen 😉

    Graphics::TBitmap *s = new Graphics::TBitmap();
    TCanvas *canvas = new TCanvas();
    canvas->Handle = GetWindowDC(GetDesktopWindow());
    
    TRect source;
    GetWindowRect(GetDesktopWindow(),(LPRECT)&source);
    s->Width = source.Right;
    s->Height = source.Bottom;
    s->Canvas->CopyRect(s->Canvas->ClipRect,canvas,source);
    
    //mach was mit s
    
    s->FreeImage();
    delete s;
    

    greetz KN4CK3R

    Danke, aber wenn du so ungerne deine codes Zeig, hättest sagen gleich sagen können, dass da Canvas hin muss oder etwas ähnlich beschreiben, ich habe schon Beispiele gesehen, aber dachte, man braucht es nur wenn man als Datei speichern will.
    Abgesehn davon muss ja irgendwo stehen wie es geht . 😉

    EDIT: Den Fehler kommt immer noch.



  • der Canvas Teil ist der VCL Ersatz für den BitBtl-Aufruf. Probier den Code mal außerhalb von deinem Timer und schau obs dann funktioniert.

    greetz KN4CK3R



  • Hab es bei einen Button OnClick rein, hilft nicht, ich kriege immer die Fehlermeldung:

    Im Projekt xxx.exe ist eine Exception der Klasse EInvalidGraphicOperation mit der Meldung "Bereichsüberschreitung bei Zeilenindex" aufgetreten.
    
    Graphics::TBitmap *bmp = new Graphics::TBitmap();
    	   TCanvas *canvas = new TCanvas();
    		canvas->Handle = GetWindowDC(GetDesktopWindow());
    
    		TRect source;
    	GetWindowRect(GetDesktopWindow(),(LPRECT)&source);
    	bmp->Width = source.Right;
    	bmp->Height = source.Bottom;
    	bmp->Canvas->CopyRect(bmp->Canvas->ClipRect,canvas,source);
    
    	  //ForLoL->Image1->Picture->Bitmap=bmp;
    
    	   for(scanx=0; scanx <= bmp->Width; scanx++)
    		{
    
    		 ypix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scany]);
    	   if(ypix->rgbtBlue == 100 && ypix->rgbtGreen==255 && ypix->rgbtRed ==255)
    			 {
    				MessageBox(0,"Gefunden","test1",MB_OK);
    			 }
    		for(scany=0; scany <= bmp->Height; scany++)
    			{
    
    			}
    		}
    		bmp->FreeImage();
         delete canvas;
    		delete bmp;
    


  • ich seh nirgendswo ne Definition von scany vor der Schleife (die übrigends keinen Sinn ergibt). Schau dir nochmal an, wie du mit RGBTriple richtig arbeitest.

    greetz KN4CK3R



  • KN4CK3R schrieb:

    ich seh nirgendswo ne Definition von scany vor der Schleife (die übrigends keinen Sinn ergibt). Schau dir nochmal an, wie du mit RGBTriple richtig arbeitest.

    greetz KN4CK3R

    Global:

    int scanx=0;
    int scany=0;
    TRGBTriple *xpix;
    TRGBTriple *ypix;
    

    Hab die Schleifen geändert:

    for(scanx=0; scanx < bmp->Width; scanx++)
    		{
    		for(scany=0; scany < bmp->Height; scany++)
    			{
    			ypix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scany]);
    			 if(ypix->rgbtBlue == 100 && ypix->rgbtGreen==255 && ypix->rgbtRed ==255)
    			 {
    				MessageBox(0,"Gefunden","test1",MB_OK);
    			 }
    			}
    		}
    

    So wie ich es verstehe:
    Die x Schleife fängt an mit 0, trifft dann auf die y Schleife. Y läuft dann bis es aus der Bildschirmrand trifft, dabei wird jedes Pixel von ScanLine überprüft und TRGBTriple gibt halt die 3 Farben an ypix weiter, bei der if abfrage wird jede Farbe überprüft um Herauszufinden ob die gewünschte Farbe sich gerade auf dem pixel befindet. Wenn Y-Schleife den Bildschirm erreicht läuft die X-Schleife um 1pixel weiter. Und so läuft alles bis X-Schleife über den Rand kommt.



  • nö, die linke Pixelreihe wird von oben nach unten bmp->Width mal durchsucht, zur Seite geht da nichts

    greetz KN4CK3R



  • for(scanx=0; scanx < bmp->Width; scanx++)
    		{
    		 xpix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scanx])
    		for(scany=0; scany < bmp->Height; scany++)
    			{
    			ypix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scany]);
    			 if(ypix->rgbtBlue == 100 && ypix->rgbtGreen==255 && ypix->rgbtRed ==255)
    			 {
    				MessageBox(0,"Gefunden","test1",MB_OK);
    			 }
    			}
    		}
    

    😕
    Ich glaube da fehlt noch was, werde mal darüber schlaffen, fällt mir jetzt nicht ein.



  • ich hab schonmal gesagt, du sollst dir anschauen, was ScanLine macht. Da kommt ein Pointer auf eine Zeile von links nach rechts zurück, die kannst du einfach als Array benutzen.

    Ermöglicht einen indizierten, zeilenweisen Zugriff auf Pixel.

    greetz KN4CK3R



  • TRGBTriple *xpix; //Global
    TRGBTriple *ypix; //Global
    
    for(scany=0; scany < bmp->Height; scany++)
    		{
    		ypix = (TRGBTriple *)bmp->ScanLine[scany];
    		for(scanx=0; scanx < bmp->Width; scanx++)
    			{
    			xpix = (TRGBTriple *)bmp->ScanLine[scanx];
    
    			 if(ypix[scanx].rgbtBlue == 100 && ypix[scanx].rgbtGreen==255 && ypix[scanx].rgbtRed ==255)
    			 {
    				MessageBox(0,"Gefunden","test1",MB_OK);
    			 }
    			}
    		}
    

    So ungefähr?



  • nein, du brauchst nur einen Aufruf von ScanLine, danach den Pointer der zurückkommt mit x als Array benutzen. Den zweiten Aufruf kannst du wieder rauslöschen, der wird nicht gebraucht.

    greetz KN4CK3R



  • Das muss es jetzt aber sein.

    for(scany=0; scany < bmp->Height; scany++)
    		{
    		ypix = (TRGBTriple *)bmp->ScanLine[scany];
    		for(scanx=0; scanx < bmp->Width; scanx++)
    			{
    			 if(ypix[scanx].rgbtBlue == 100 && ypix[scanx].rgbtGreen==255 && ypix[scanx].rgbtRed ==255)
    			 {
    				MessageBox(0,"Gefunden","test1",MB_OK);
    			 }
    			}
    		}
    


  • ja jetzt sollte es funktionieren

    greetz KN4CK3R



  • Also nochmal zu dem ganzen:

    if(scanthread==true)
    	  {
    	   Graphics::TBitmap *bmp = new Graphics::TBitmap();
    	   TCanvas *canvas = new TCanvas();
    		canvas->Handle = GetWindowDC(GetDesktopWindow());
    
    		TRect source;
    	   GetWindowRect(GetDesktopWindow(),(LPRECT)&source);
    	   bmp->Width = source.Right;
    	   bmp->Height = source.Bottom;
    	   bmp->Canvas->CopyRect(bmp->Canvas->ClipRect,canvas,source);
    
    	   for(scany=0; scany < bmp->Height; scany++)
    		{
    		ypix = (TRGBTriple *)bmp->ScanLine[scany];
    		for(scanx=0; scanx < bmp->Width; scanx++)
    			{
    			 if(ypix[scanx].rgbtBlue == 79 && ypix[scanx].rgbtGreen==162 && ypix[scanx].rgbtRed ==223)
    			 {
    				MessageBox(0,"Gefunden","test1",MB_OK);
    			 }
    			}
    		}
    
    		bmp->FreeImage();
    		delete bmp;
    		delete canvas;
    	  }
    	  Sleep(10);
       }
    

    Scheint zu funtionieren, vielen dank. Wenn jemand noch irgendwelche vorschläge hat, bitte posten.


Anmelden zum Antworten