PixelFormat=pf24bit versucht Arbeitsspeicherüberlastung



  • kpeter schrieb:

    Weiter oben schrieb ich schon mal, dass du Application->ProcessMessages setzen sollst,
    wenn deine if-Bedingung erfüllt ist.
    Was sk.SendKeys("w"); bewirkt, hast du bisher nicht geschrieben. Du musst
    deiner Anwendung Zeit geben, alle Messages erst einmal zu verarbeiten...

    Ich glaube du hast mich nicht verstanden. Sobald die scanthread=true ist fängt an der Verbrauch der Arbeitsspeicher ständig zu steigern. Dabei wird weder die MessageBox noch die sk.SendKeys ausgeführt. Weil if garnicht zustimmt.

    sk.SendKeys ist nur eine Funtion die keybd_event ausführt.

    Und noch was, alles was ich noch nicht erwähnt hab ist das was keinen Einfluss auf das Problem hat. Ich habe alles gestest bzw ohne diese Funtionen gestartet.



  • Hmm.
    In Zeile 21 schreibst du in die Struktur TRGBTriple rein. Eher für 24 Bit-BMPs.
    Versuchs mal mit RGBQUAD, 4-BYTE-Struktur. Ansatz:

    RGBQUAD *ptr;
    
    for (int y = 0; y < bmp->Height; y++) {
       ptr = (RGBQUAD*)bmp->ScanLine[y];
       for (int x = 0; x < bmp->Width; x++) {
          if (ptr[x].rgbRed 	== 255 &&
          .
          .
    


  • An dem Ergebnis hat sich leider nichts geändert. Passiert genau das selbe wie mit dem TRPGTriple.



  • Nun, wenn ich mir diesen und auch den vorhergehenden Thread betrachte, muss ich feststellen, dass du im Prinzip immer denselben Code postest.

    Insbesondere hast du folgende Hinweise nicht beachtet:
    Erstellen der Bitmap NICHT in der ScanFunc, sondern schon vor Aufruf des Thread. Schliesslich bleibt die Grösse konstant.
    Das ReleaseDC ist fehlerhaft. Hättest du meinen Hinweis (Link) beachtet, müsstest du diese Funktion einschl. GetWindowDC nicht mal verwenden.
    Auch das Erstellen eines TCanvas wäre unnötig, da in der API-Funktion BitBlt direkt das Handle des DC des Bitmap
    übergeben wird.
    Deine Scanfunktion ist nicht korrekt; sie müsste einen return-Wert zurückgeben.
    Keine Ahnung, wie gross dein Monitor ist, aber da du ja permanent scannst, sollte diese Funktion auch so kurz wie möglich gehalten
    werden.
    Mit welchem Tool stellst du deine Arbeitsspeicherüberlastung fest?



  • kpeter schrieb:

    Insbesondere hast du folgende Hinweise nicht beachtet:
    Erstellen der Bitmap NICHT in der ScanFunc, sondern schon vor Aufruf des Thread. Schliesslich bleibt die Grösse konstant.

    Hab ich schon versucht, da das Ergebnis sich nicht geändert hat hab ich es so gelassen.

    kpeter schrieb:

    Das ReleaseDC ist fehlerhaft. Hättest du meinen Hinweis (Link) beachtet, müsstest du diese Funktion einschl. GetWindowDC nicht mal verwenden.
    Auch das Erstellen eines TCanvas wäre unnötig, da in der API-Funktion BitBlt direkt das Handle des DC des Bitmap
    übergeben wird.

    Wieso ist ReleaseDC fehlerhaft? Ansonsten hab ich mit BitBlt schon mal versucht und wie in dem Beispiel nachgebaut:

    DWORD WINAPI ScanFunc( LPVOID lpParam )
    {
     while(whilethread==true)
     {
      if(scanthread==true)
      {
       Graphics::TBitmap *bmp = new Graphics::TBitmap();
       dc = GetWindowDC(GetDesktopWindow());
       hBitmap = CreateCompatibleBitmap(dc, iSizeW, iSizeH);
       HDC hdcTemp = CreateCompatibleDC(dc);
       bmp->PixelFormat=pf24bit;
       bmp->Width = iSizeW;
       bmp->Height = iSizeH;
       BitBlt(bmp->Canvas->Handle, 0, 0, bmp->Width, bmp->Height, dc, 0, 0, SRCCOPY);
    
       for(scany=0; scany < bmp->Height; scany++)
       {
    	ypix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scany]);
    	for(scanx=0; scanx < bmp->Width; scanx++)
    	{
    	  if(ypix[scanx].rgbtBlue == 49 && ypix[scanx].rgbtGreen==247 &&
    		ypix[scanx].rgbtRed ==255)
    	 {
    	  MessageBox(0,"Gefunden","test1",MB_OK);
    	 }
    	}
       }
      bmp->FreeImage();
      ReleaseDC(0,dc);
      delete bmp;
      }
      Sleep(100);
     }
     return 0;
    }
    

    Was ist danran falsch? 😕

    kpeter schrieb:

    Mit welchem Tool stellst du deine Arbeitsspeicherüberlastung fest?

    Task-Manager->Processe. Da steht welches Process wie viel Speicher verbraucht. Ich weiß nicht genau ob es unter XP schon gabs(glaub schon) aber ich habe Windiws 7.
    Und genau dort fängt an die Zahl zu wachsen sobald ich den scanthread auf true setze.



  • Was ist das denn hier plötzlich in deinen Zeilen 9 und 10 ???

    igromanru schrieb:

    hBitmap = CreateCompatibleBitmap(dc, iSizeW, iSizeH);
       HDC hdcTemp = CreateCompatibleDC(dc);
    

    Wird doch nie verwendet???

    Die Funktion ReleaseDC ist hier beschrieben. Auch welche Parameter erwartet werden.



  • Die Zwei Zeilen hab ich ausversehen mit übergenommen.
    Und was dir an dem ReleaseDC nicht gefällt verstehe ich auch nicht.
    Ich habe jetzt mal so gemacht, aber besser wurde davon jetzt auch nicht:

    DWORD WINAPI ScanFunc( LPVOID lpParam )
    {
     while(whilethread==true)
     {
      if(scanthread==true)
      {
       Graphics::TBitmap *bmp = new Graphics::TBitmap();
       DeskH =  GetDesktopWindow();
       dc = GetWindowDC(GetDesktopWindow());
       bmp->PixelFormat=pf24bit;
    
       bmp->Width = iSizeW;
       bmp->Height = iSizeH;
       BitBlt(bmp->Canvas->Handle, 0, 0, bmp->Width, bmp->Height, dc, 0, 0, SRCCOPY);
    
       for(scany=0; scany < bmp->Height; scany++)
       {
    	ypix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scany]);
    	for(scanx=0; scanx < bmp->Width; scanx++)
    	{
    	  if(ypix[scanx].rgbtBlue == 49 && ypix[scanx].rgbtGreen==247 &&
    		ypix[scanx].rgbtRed ==255)
    	 {
    	  MessageBox(0,"Gefunden","test1",MB_OK);
    	 }
    	}
       }
    
      bmp->FreeImage();
      ReleaseDC(DeskH,dc);
      delete bmp;
      }
      Sleep(100);
     }
     return 0;
    }
    


  • Hallo,

    Das FreeImage hier brauchst du nicht. Weietrhin würde ich das Erzeugen und zerstören des Bitmaps aus der while-Schleife nehmen.



  • Braunstein schrieb:

    Hallo,

    Das FreeImage hier brauchst du nicht. Weietrhin würde ich das Erzeugen und zerstören des Bitmaps aus der while-Schleife nehmen.

    Hab ich mal versucht. Hab dabei folgendes bemerkt:
    Wenn

    bmp = new Graphics::TBitmap();
    

    oder

    bmp->PixelFormat=pf24/*32*/bit;
    

    nur 1mal festgelegt wird, gibt es zwar keine Arbeitsspeicherüberstung aber dafür funktioniert es nicht.
    Hab versucht und hab wie du sagtest,

    Graphics::TBitmap *bmp = new Graphics::TBitmap()
    

    und

    delete bmp;
    

    außerhalb der Schleife gemacht und nach dem es nicht geklappt hat, hab ich wieder zurück umgebaut und hab

    bmp->PixelFormat=pf24/*32*/bit;
    

    nur 1mal ausführen gelassen:

    if(test011==true)
       {
       bmp->PixelFormat=pf24bit;
       test011 = false;
       }
    

    Ja, und wie gesagt, Funtion geht nicht, dafür ist aber alles OK mit dem Speicher.



  • So, ich schreibe wieder, weil ich fast herausgefunden an was es liegt, dass es nicht funtioniert.
    Alles was nicht drin ist, wird wo anders ausgeführt. z.B. delete bmp; steht unter dem OnClose event.

    DWORD WINAPI ScanFunc( LPVOID lpParam )
    {
     while(whilethread==true)
     {
      if(scanthread==true)
      {
       DeskH = GetDesktopWindow();
       dc = GetWindowDC(DeskH);
       bmp->PixelFormat=pf24bit;
       BitBlt(bmp->Canvas->Handle, 0, 0, bmp->Width, bmp->Height, dc, 0, 0, SRCCOPY);
    
       for(scany=0; scany < bmp->Height; scany++)
       {
    	ypix = reinterpret_cast<TRGBTriple *>(bmp->ScanLine[scany]);
    	for(scanx=0; scanx < bmp->Width; scanx++)
    	{
    	  if(ypix[scanx].rgbtBlue == 49 && ypix[scanx].rgbtGreen==247 &&
    		ypix[scanx].rgbtRed ==255)
    	 {
               sk.SendKeys("{BEEP 350 300}");
    	  //MessageBox(0,"Gefunden","test1",MB_OK);
    	 }
    	}
       }
      ReleaseDC(DeskH,dc);
      }
      Sleep(100);
     }
     return 0;
    }
    

    Also, was passiert hier:
    Keine Arbeitsspeicherüberlastung.
    Dafür aber macht er irgendwie nur einmal screen shot oder so was in der art.
    Wenn ich das Bild wo sich die gewünschte Farbe öffne und erst dann die Funtion lauden lasse, dann findet er die farbe

    sk.SendKeys("{BEEP 350 300}");
    

    Macht beep Geräusche und so weiß ich, dass es die Farbe findet. Wenn ich das Bild minimiere hört es nicht auf zu beepen. Deshalb gehe ich davon aus, dass irgendwas nicht überschrieben wird.
    Hat jemand eie Idee?


Anmelden zum Antworten