Announcement

Collapse
No announcement yet.

CreateCompatibleBitmap schlägt fehl -> zu wenig Speicher??

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • CreateCompatibleBitmap schlägt fehl -> zu wenig Speicher??

    Hallo,

    ich versuche mit dem unten stehenden Codeabschnitt einen Scrennshot von einem Fenster zu machen und als Bitmap zwecks Überprüfung auf einem QLabel (Qt Creator) anzuzeigen. Später soll das Bild dann mit Hilfe von OpenCV weiterverarbeitet werden. Dieser "Screenshot" soll außerdem, über einen Slider einstellbar, 1-30 mal pro Sekunde erstellt und angezeigt werden (der Code unten wird dementsprechend wiederholt aufgerufen).

    Das funktioniert auch erstmal wie es soll, aber nach einiger Zeit (je höher die Framerate desto früher) scheint CreateCompatibleBitmap() fehlzuschlagen!! LastError ergibt 8, was wohl bedeutet, dass der Speicher (zu) knapp ist??

    Code:
    #include "mainwindow.h"
    #include "ui_mainwindow.h"
    
    #include <opencv2/opencv.hpp>
    #include <windows.h>
    #include <qtimer.h>
    #include <QMessageBox>
    
    QPixmap GetScreenshot (QWidget *parent)
    {
        HWND winHandle = FindWindow(NULL, TEXT("Rechner"));
        HDC hDCMem, hDC;
    
        if(!winHandle)
        {
            QMessageBox::information(parent, "", "Fenster 'Rechner' nicht gefunden!", QMessageBox::Ok);
        }
    
        hDC = GetWindowDC(winHandle); //GetDC()?
        if(!hDC)
        {
            QMessageBox::information(parent, "", "GetWindowDC() fehlgeschlagen!", QMessageBox::Ok);
        }
    
        hDCMem = CreateCompatibleDC(hDC);
        if(!hDCMem)
        {
            QMessageBox::information(parent, "", "CreateCompatibleDC() fehlgeschlagen!", QMessageBox::Ok);
        }
    
        RECT rc;
        GetWindowRect(winHandle, &rc);
    
        HBITMAP hbitmap = CreateCompatibleBitmap(hDC, rc.right-rc.left, rc.bottom-rc.top);
    
        if(!hbitmap)
        {
            int error = GetLastError();
            QMessageBox::information(parent, "", "CreateCompatibleBitmap() fehlgeschlagen! (Last error = " + QString::number(error) + ")", QMessageBox::Ok);
            return 0;
        }
    
        SelectObject(hDCMem, hbitmap);
        if(!BitBlt(hDCMem, 0, 0, rc.right-rc.left, rc.bottom-rc.top, hDC, 0, 0, SRCCOPY))
        {
            //QMessageBox::information(parent, "", "BitBlt() fehlgeschlagen!", QMessageBox::Ok);
        }
    
        QPixmap PixelKarte = QPixmap::fromWinHBITMAP(hbitmap, QPixmap::NoAlpha);
    
        ReleaseDC(winHandle, hDC);
        ReleaseDC(winHandle, hDCMem);
        DeleteObject(hbitmap);
    
        return PixelKarte;
    }
    Was mich irritiert ist, dass es erstmal funktioniert... Habe ich vergessen irgendwas am Ende dieser Prozedur freizugeben, sodass der Speicher vollgemüllt wird o.ä.?? Habe gelesen, dass man wohl auch CreateDIBSection() nehmen kann oder soll (bei hohem Speicheraufkommen), aber ich bin nicht sicher, ob es das ist was ich brauche (hab es auch nicht zum Laufen gebracht)...

    Es wäre mir eine große Hilfe, wenn mir jemand auf die Sprünge helfen könnte!

    Vielen Dank!

    Gruß jacob2
    MfG Jacob2

    Meine Website mit Roboter-, Elektronik- und Softwareprojekten: www.roboterbastler.lima-city.de

  • #2
    Erstaunlich, es programmiert noch jemand direkt gegen die API. Kenne nun QT nicht, aber


    QPixmap PixelKarte = QPixmap::fromWinHBITMAP(hbitmap, QPixmap::NoAlpha);

    das wird immer neu angelegt. Ansonsten würde ich sagen, das alles freigegeben wird.
    Christian

    Comment


    • #3
      Originally posted by Christian Marquardt View Post
      Erstaunlich, es programmiert noch jemand direkt gegen die API.
      Der Weg über die API ist die einzige mir bekannte Lösung dieses Problems, was aber nichts heißen muss...

      Durch beobachten im Taskmanager habe ich herausgefunden, dass während das Programm läuft bis zu dem Fehlschlag die Auslagerungsdatei von ~760MB auf 1,07GB hochgeht und unter "Kernel-Speicher" der ausgelagerte Teil von ~48 MB auf etwa 351MB ansteigt. Die Speicherauslastung die für den Prozess angezeigt wir bleibt aber kostant bei um 20 MB.

      Sagt dir das eventuell etwas?? Auffällig ist auch, dass die Auslagerungsdatei eine Weile konstant bleibt und erst dann ansteigt. Ich kenne mich da nicht so gut aus, deshalb weiß ich nicht, ob diese Beobachtungen etwas bringen.

      Alternativ habe ich auch dieses "Ende" ausprobiert, es ändert aber nichts:

      Code:
          //QPixmap PixelKarte = QPixmap::fromWinHBITMAP(hbitmap, QPixmap::NoAlpha);
      
          ReleaseDC(winHandle, hDC);
          ReleaseDC(winHandle, hDCMem);
          //DeleteObject(hbitmap);
      
          //return PixelKarte;
          return QPixmap::fromWinHBITMAP(hbitmap, QPixmap::NoAlpha);
      Danke auf jeden Fall schonmal für deine (auch aus früheren Erfahrungen) sehr flotten Antworten!!
      MfG Jacob2

      Meine Website mit Roboter-, Elektronik- und Softwareprojekten: www.roboterbastler.lima-city.de

      Comment


      • #4
        Ok, ich hab das Speicherleck gefunden:
        hDCMem wird mit CreateCompatibleDC() erzeugt und muss daher nicht mit ReleaseDC() sondern mit DeleteDC() freigegeben werden...
        MfG Jacob2

        Meine Website mit Roboter-, Elektronik- und Softwareprojekten: www.roboterbastler.lima-city.de

        Comment

        Working...
        X