Mysteriöses Verhalten in Zusammenhang mit Bitmap->Assign(...)?



  • Hallo,

    mittels einer Methode lade ich ein Bild, passe es von der Größe her an eine PaintBox an und weise es dieser zu. Wiederhole ich diesen Vorgang, zeigt sich das Bild unerklärlicherweise in anderer Größe.

    Um diesem Mysterium auf die Spur zu kommen, erstelle ich einige Debug-Ausgaben zur Anzeige verschiedener Eigenschaften, Bitmap-Width etc. - und Wunder oh Wunder, das Problem hat sich in Luft aufgelöst.

    Das heißt, eine einfache Zuweisung z.B. zu einer ListBox genügt, um dieses Problem zu beseitigen.

    ListBox_Debug->Items->Add("zeige Eigenschaft ...");
    

    Kann mir das jemand erklären?!

    Gruß Leo

    Nachfolgend der Beispiel-Code:

    void __fastcall TForm_Main::konvertiere_fuer_PaintBox(Graphics::TBitmap *pBitmap)
    {
        // Zweck: prüft das Quell-Bitmap pBitmap auf Hoch- oder Querformat und passt es der Größe
        //        der PaintBox PaintBox1 an.
    
        // erwartet:
        // - Graphics::TBitmap *pBitmap: Quell-Bitmap
        // - PaintBox1: PaintBox-Objekt
    
        // Arbeitsweise:
        // - das vorliegende Bildformat ermittelt (hoch/quer) und zu PaintBox1
        //   ins Verhältnis setzen
        // - das resultierende Rechteck RectPic_Screen zur Dimensionierung des
        //   temporären Bitmap pBitmap_temp verwenden
        // - das Quell-Bitmap per StretchDraw in das temporäre Bitmap kopieren
        // - per Assign das temporäre Bitmap dem Quell-Bitmap zuweisen
    
        // Verhältnisse von pBitmap und PaintBox1 ermitteln
        double dQt_bitmap = (double)pBitmap->Width / pBitmap->Height;
        double dQt_screen = (double)PaintBox1->Width / PaintBox1->Height;
        int iHoehe, iOben, iBreite, iLinks;
        TRect RectPic_Screen;
    
        // Erkennen, ob Bild im Hoch- oder Querformat vorliegt
        // Erl.
        // Wenn dQt_bitmap > 0, dann hat Bild Querformat
        //    Wenn dQt_screen < dQt_bitmap, d.h. wenn ausreichend Bildschirmhöhe, d.h. wenn Seitenverhältnis (SV) screen < SV bitmap
        //    Wenn dQt_screen > dQt_bitmap, d.h. wenn ausreichend Bildschirmbreite, d.h. wenn Seitenverhältnis (SV) screen > SV bitmap
        //
        // Wenn (Querformat UND SV screen < SV bitmap) ODER (NICHT Querformat UND SV screen > SV bitmap
        if(dQt_bitmap > 0 && dQt_screen < dQt_bitmap || !dQt_bitmap > 0 && dQt_screen > dQt_bitmap){ // Quer-Format
            iHoehe = RoundTo((double)PaintBox1->Width / dQt_bitmap, 0);
            iOben = RoundTo((double)(PaintBox1->Height - iHoehe)/2, 0);
            RectPic_Screen = Rect(0, iOben, PaintBox1->Width, iOben+iHoehe);
        }else{  // Hoch-Format
            iBreite = RoundTo((double)PaintBox1->Height * dQt_bitmap, 0);
            iLinks = RoundTo((double)(PaintBox1->Width - iBreite)/2, 0);
            RectPic_Screen = Rect(iLinks, 0, iLinks+iBreite, PaintBox1->Height);
        }
    
        Graphics::TBitmap *pBitmap_temp;
        pBitmap_temp = new Graphics::TBitmap();
        pBitmap_temp->Width = RectPic_Screen.Width();
        pBitmap_temp->Height = RectPic_Screen.Height();
    
        // pBitmap per StretchDraw an pBitmap_temp
        pBitmap_temp->Canvas->StretchDraw(Rect(0, 0, RectPic_Screen.Width(), RectPic_Screen.Height()), pBitmap); // Bitmap_Pic auf Hauptbitmap kopieren
        pBitmap->Assign(pBitmap_temp); // temporäres Bitmap an pBitmap übergeben
    
        // ! Ohne die folgende Anweisung tritt der Fehler auf !
        ListBox_Debug->Refresh();
    
        delete pBitmap_temp;
    }
    //---------------------------------------------------------------------------
    


  • Im Debug-Build ohne Laufzeitpackages kannst du in den VCL-Quelltext steppen. Damit sollte es möglich sein herauszufinden, was die Ursache für das Verhalten ist.



  • audacia schrieb:

    Im Debug-Build ohne Laufzeitpackages kannst du in den VCL-Quelltext steppen. Damit sollte es möglich sein herauszufinden, was die Ursache für das Verhalten ist.

    Danke für die Antwort, die mir aber ohne Erläuterungen nicht weiterhilft.

    Ich benutzte den C++ Builder 6.0 (Enterprise Suite)

    Wie stelle ich es an, im Debug-Build ohne Laufzeitpackages in den VCL-Quelltext zu steppen? Und warum soll ich das tun? - Ein paar mehr Hinweise wären schon hilfreich.

    Gruß Leo



  • Leo Freitag schrieb:

    Ich benutzte den C++ Builder 6.0 (Enterprise Suite)

    Wie stelle ich es an, im Debug-Build ohne Laufzeitpackages in den VCL-Quelltext zu steppen?

    Da gibt es im Linker-Tab in den Projekteinstellungen ein Häkchen namens "Mit Debug-Bibliotheken", das du anwählen mußt. Und halt ohne Laufzeitpackages linken wie oben beschrieben.

    Leo Freitag schrieb:

    Und warum soll ich das tun? - Ein paar mehr Hinweise wären schon hilfreich.

    Grundsätzlich deshalb, weil du dir jegliche Frage zum Verhalten von RTL und VCL selbst beantworten kannst, wenn du einfach im Quelltext nachschaust. Und das geht besonders komfortabel mit dem Debugger, weil du deinen Aufrufen von RTL-/VCL-Funktionen einfach folgen kannst.

    Es kann sein, daß jemand das Problem schonmal hatte und die Lösung hier postet. Falls aber nicht, dann müßte sich jemand die Zeit nehmen und das Problem eingehend analysieren, d.h. mithilfe von Quelltext und Debugger das Verhalten der VCL in diesem Fall verstehen. Und mein Vorschlag ist lediglich, daß, anstatt zu warten, bis jemand dafür Zeit hat, du das einfach selber machst 🙂



  • audacia schrieb:

    Da gibt es im Linker-Tab in den Projekteinstellungen ein Häkchen namens "Mit Debug-Bibliotheken", das du anwählen mußt. Und halt ohne Laufzeitpackages linken wie oben beschrieben.

    Ok, funktioniert! Jetzt steppe ich durch jede Menge Delphi-Code ...

    audacia schrieb:

    (...) deshalb, weil du dir jegliche Frage zum Verhalten von RTL und VCL selbst beantworten kannst, wenn du einfach im Quelltext nachschaust.

    Äh, öh, einfach nachschauen?
    Ich suche ja nach einer Antwort auf die Frage, warum die Darstellungsgröße eines Bildes beim ersten Aufruf 'so' und bei jedem weiteren Aufruf 'so-nicht' ist.
    Dazu durchsteppe ich den Code nach Eigenschaften wie Bitmap-Size, Screen-Size etc. und verliere mich schließlich in einer Schleife der Function GetHashCode, aus der der Debugger nicht wieder raus will ...

    Also, vielen Dank für den aufgezeigten Weg, nur mit "einfach im Quelltext nachschauen" ist es für mich nicht getan.

    Gibt es vielleicht einen anderen Lösungsansatz?

    Gruß Leo


Anmelden zum Antworten