Bitmap lädt mittels LoadImage Funktion nicht immer



  • Hallo,

    Ich habe diese Frage vorhin auch in einem anderen Forum gestellt, und dachte ich poste es mal paralell auch hier. Sollte ich die Lösung im anderen Forum erhalten, werde ich sie hier posten. Umgekehrt auch.

    Das Problem ist folgendes: Ich programmiere mittels Dev-Cpp Editor eine Winapi Anwendung (Win32) und habe erfolgreich mittels der LoadImage Funktion ein Bild laden können. Dieses Bild befindet sich im selben Ordner wie die ausführbare Datei.

    [code="cpp"]
    hbmp = (HBITMAP) LoadImage(NULL, "test.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);[/code="cpp"]

    Problem: Wenn ich ein anderes bitmap, auch aus dem selben Ordner, versuche zu laden, gibt hbmp NULL zurück. Das andere Bitmap, übrigens mit dem Namen "bp.bmp", wird nicht angezeigt, obwohl es sich im selben Ordner wie "test.bmp" befindet. Die Frage ist wieso?
    bp.bmp wurde übrigens mit Corel PhotoPaint erstellt, und test.bmp mit paint.

    Eigene Ideen / Ansätze:

    - Vielleicht war der Name der Datei anfangs mit über 20 chars zu lang, denn die bitmap hieß vorher anders und länger, aber daran lag es nicht. Ich weiß nicht in wieweit "LPCTSTR lpszName" von der Größe her beschränkt ist. Wie gesagt, das war's auch nicht.

    - ich habe bp.bmp mal in Paint geladen und von dort auch nochmal gespeichert und getestet, da ich nicht weiß, wie die Programme intern eine Bitmap unterschiedlich speichern, denn Bitmap ist ja nicht gleich Bitmap. Aber auch das funktioniert nicht.

    - Wenn ich mit Paint eine neue Bitmap erstelle, die ich test2.bmp nenne, funktioniert es merkwürdiger weise aber wieder. Er zeigt diese Bitmap also an.

    Woran liegt das also? Es kann auch wirklich an Dev-Cpp liegen, denn ich hab das Gefühl, dass die Dateien, wenn sie geändert werden, nicht immer aktualisiert werden. Aber er erkennt ja, dass ich eine neue Bitmap versuche zu laden, denn "hbmp" kriegt ja einen neuen Wert, den ich auch abfrage.

    Ich weiß da momentan echt irgendwie nicht weiter. Aber vielleicht ist das ja einem von euch schonmal ähnlich passiert? 😞

    Danke für schnelle Hilfe,
    Paddle



  • Vielleicht hat sich Dein CurrentDirectory geändert... geb dieses Mal vor dem Aufruf der Methode aus...


  • Mod

    Anschließend an das was Jochen sagt würde ich Dir grundsätzlich raten immer volle Pfade bei so etwas zu benutzen.

    Andere Frage: Warum platzierst Du die Bitmap nicht in die essourcen?



  • @Paddle
    Warum fragst du den Fehler nicht erst mal mit GetLastError ab, anstatt lange rumzuraten 😕



  • Hey,

    Also das Verzeichnis ändert sich nicht. Es bleibt bei der .bmp Datei, die funktioniert, und bei der, die nicht Funktioniert gleich.

    GetLastError hat die Meldung "Der Vorgang wurde erfolgreich beendet!" gebracht. Entweder nutze ich diese Funktion falsch (GetLastError -> FormatMessage usw.), oder sie ist generell wenig hilfreich. Zumindest meine eigenen Fehlermeldungen sagen da mehr aus.

    Meine einzige Idee wäre momentan wirklich nur, dass LoadImage eventuell nicht mit jedem Bitmap Format klar kommt, denn alle .bmp, die ich mit Paint erstelle funktionieren ja. Nur die Bitmap, die ich mit dem guten Grafik Programm gemacht habe nicht 😃
    Und das öffnen der guten .bmp in Paint und das erneute Speichern dort, bringen leider auch nichts. Wahrscheinlich, weil Paint diese spezielle .bmp dann nicht mehr umformt oder so.

    Fällt noch wem was ein?



  • Hey,

    Das Problem ist gelöst. Es liegt daran, dass LoadImage eine 24 Bit Bitmap erwartet und Corel Photoshop hat einen anderen Bitmaptypen verwendet.


  • Mod

    Paddle schrieb:

    Das Problem ist gelöst. Es liegt daran, dass LoadImage eine 24 Bit Bitmap erwartet und Corel Photoshop hat einen anderen Bitmaptypen verwendet.

    Kann nicht sein. LoadImage lädt so ziemlich alle Bitmapformen.



  • Ich hab es ja ausprobiert. 32 Bit Bitmaps funktionieren aus irgendeinem Grund nicht. Das kann viele Gründe haben. Vielleicht werden die intern wirklich anders gespeichert oder die Bibliothek ist veraltet. Anders kann ich mir das nicht erklären.



  • Ich habe noch nie Probleme mit LoadImage und 32bpp Bitmaps gehabt.
    Hast Du geprüft ob Dir ein gültiges Handle zurückgegeben wird ?
    GetLastError scheint ja "alles OK" zurückzugeben.
    Ich denke eher es liegt an den Funktionen die Du zum Anzeigen der Bitmap verwendest ...

    :xmas1: Grüße
    Greenhorn



  • Hey,

    Ich benutze ja einen selbst programmierten DEBUG Modus, der immer an ist, wenn ich Sachen ausprobiere. Dort frage ich unter anderem sämtliche handles, aber auch andere Funktionen ab. Dort wird zumindest nichts falsches zurückgeliefert. Und der Code ist ja dafür auch nicht so lang. Hier mal Code Ausschnitte:

    WM_CREATE:

    hBMPintro = (HBITMAP) LoadImage(NULL, ".\\graphics\\bm24_bgp.bmp", IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
          Bytes = GetObject(hBMPintro, sizeof(BITMAP), &BMPintro);
    
          #ifdef DEBUG_MODE
            if (hBMPintro == NULL) MessageBox(WPhwnd, "LoadImage() returns NULL.", "Error", MB_OK);
            if (Bytes == 0) MessageBox(WPhwnd, "GetObject() returns 0.", "Error", MB_OK);
          #endif
    

    WM_PAINT:

    hDeCo                = BeginPaint(WPhwnd, &ps);
            hDeCoMem             = CreateCompatibleDC(hDeCo);
            SelectObject(hDeCoMem, hBMPintro);
            flag                 = BitBlt (hDeCo, 0, 0, BMPintro.bmWidth, BMPintro.bmHeight, hDeCoMem, 0, 0, SRCCOPY) ; 
    
            #ifdef DEBUG_MODE
              if (!flag) MessageBox(WPhwnd, "BitBlt() returns 0.", "Error", MB_OK);
            #endif
    
            flag                 = DeleteDC(hDeCoMem);
    
            #ifdef DEBUG_MODE
              if (hDeCo == NULL) MessageBox(WPhwnd, "BeginPaint() returns NULL.", "Error", MB_OK);
              if (hDeCoMem == NULL) MessageBox(WPhwnd, "CreateCompatibleDC() returns NULL.", "Error", MB_OK);
              if (!flag) MessageBox(WPhwnd, "DeleteDC() returns 0.", "Error", MB_OK);
            #endif
    


  • Also, im Debugger von Visual Studio siehst Du doch den Inhalt der Variablen. Und den Rückgabewert der Funktionen auch. Da brauchst Du Deine Debug-Funktionen eigentlich nicht.

    BTW, den Speicher-Gerätekontext würde ich in der WM_CREATE erzeugen und global speichern und erst bei der WM_DESTROY löschen. Außerdem würde ich die alte Bitmap nach dem BitBlt wieder in den Speicher-Gerätekontext einfügen.

    :xmas2:



  • Hey,

    Ich benutze ja leider kein Visual Studio, sondern Dev C++. Ob der einen Debugger hat weiß ich allerdings nicht. So gesehen schadet der eigene Debugger ja nicht. Das ist zwar einmal mehr Schreibarbeit, aber ich kann gleich für eigene Ausgaben sorgen.

    Den Speicher-gerätekontext in WM_CREATE zu erzeugen ist prinzipiell vielleicht keine schlechte Idee. Aber das zweite verstehe ich nicht ganz. Ich habe ja nicht nur diese eine Bitmap? Welchen Vorteil hätte das?



  • http://msdn.microsoft.com/en-us/library/dd162957%28v=vs.85%29.aspx
    Siehe "Remarks".

    Dev C++ ist tot, von daher empfehle ich Dir VC 2010 Express.
    http://www.c-plusplus.net/forum/143003
    Und das SDK 7.1, falls Du Win7 benutzt.
    http://www.microsoft.com/en-us/download/details.aspx?id=8442

    Grüße
    Greenhorn



  • Paddle schrieb:

    So gesehen schadet der eigene Debugger ja nicht. Das ist zwar einmal mehr Schreibarbeit, aber ich kann gleich für eigene Ausgaben sorgen.

    Die Schreibarbeit kann man sich mit Makros erleichtern. Wird dadurch auch übersichtlicher.
    Bzw. bietet C++ im Header File "cassert" auch schon ein fertiges Makro namens "assert" an.


Anmelden zum Antworten