TImage->Picture->Bitmap - Größe wird trotz TImage->Stretch= true nicht verändert!?



  • Hallo Gemeinschaft,

    ich möchte ein, mit Draw gezeichnetes, Bitmap drucken. Um eine vernünftige Darstellung der Druckseite bei verschiedenen DPI-Einstellungen zu erreichen, habe ich alle Positionen der zu druckenden Elemente (ist ja nicht nur das Bitmap) relativ zu Höhe und Breite des bedruckbaren Bereiches berechnet. Sieht auch Alles bei verschieden großen bedruckbaren Bereichen und DPI-Einstellungen passig aus, nur mit dem besagten Bitmap gibt es Probleme:

    Das Bitmap liegt in einem TImage. Beide haben 824x236 Pixel. TImage-Eigenschaften: Stretch steht auf true, AutoSize auf false, Visible auf false, Enabled auf false.
    Zur Laufzeit, wenn gedruckt werden soll, wird das Seitenverhältnis des TImage (Breite / Höhe als double), die neue Bildbreite (18% der Breite des bedruckbaren Bereiches) und neue Bildhöhe (neue Bildbreite * Seitenverhältnis) berechnet. Diese habe ich mit dem Debugger kontrolliert, sie stimmen immer.
    Dann werden die neue Werte für Breite und Höhe dem TImage zugewiesen. Nun sollte die Größe des Bitmap verändert sein, da Stretch des TImage ja auf true steht... die Größe des Bitmap ändert sich nur leider nicht; das Bitmap wird, unabhängig von der Breite des bedruckbaren Bereiches, immer 824x236 groß ausgedruckt.
    Wenn ich einen Haltepunkt auf den Draw-Aufruf setze, hat das TImage eine veränderte Größe, wie es sein soll.
    Warum wird die Größe des Bitmap im TImage nicht verändert?

    MfG



  • Ohne den Code zu sehen, kann ich nur raten. Ich vermute, du passt die Größe des Bitmaps zahlenmäßig an die Größe des Images an. Dabei werden die entstehenden Ränder mit weiß aufgefüllt und Stretch kann dann nicht mehr funktionieren.



  • Nein, ich passe die Größe des TImage an. Code ist kein Problem:

    Pseudocode:

    TCanvas *Druckseite= Systemdrucker->Canvas;                                 // Zeiger auf Systemdrucker definieren
    int x= Druckbereichsbreite, y= Druckbereichshöhe;                           // bedruckbarer Bereich in Pixeln
    int Links= int(x * 0.70f), Oben= int(y * 0.055f), Rechts= int(x * 0.88f);   // Werte für Positionierung des Bitmap und für weitere Berechnungen
    TImage *pImg= ImageMitGeladenemBitmap;                                      // Zeiger auf TImage definieren (TImage= 824x236 Pixel & geladenes Bitmap= 824x236 Pixel)
    double Seitenverhältnis= double(pImg->Width) / double(pImg->Height);        // Seitenverhältnis des TImage (und damit auch des Bitmap) berechnen
    int Unten= Oben + int(double(Rechts - Links) / Seitenverhältnis);           // unteren Rand unter Berücksichtigung des Seitenverhältnis berechnen
    pImg->Width= Rechts - Links;                                                // TImage eine neue Breite zuweisen
    pImg->Height= Unten - Oben;                                                 // TImage eine neue Höhe zuweisen => da Stretch= true, sollte das Bitmap im TImage nun die passende Größe haben
    Druckseite->BeginDoc();
    Druckseite->CopyMode= cmSrcCopy;                                            // Modus: Bitmap soll kopiert werden
    Druckseite->Draw(Links, Oben, pImg->Picture->Bitmap);                       // Bitmap auf Zeichenfläche bringen => Haltepunkt hier zeigt, dass Abmessungen des TImage stimmen
    Druckseite->EndDoc();                                                       // Bitmap wird unabhängig von den obigen Bemühungen 824x236 Pixel groß ausgedruckt...???
    pImg->Width= 824;
    pImg->Height= 236;                                                          // ursprüngliche Werte wiederherstellen
    

    Danke für's Drüberschauen...

    Edit: Ich habe noch eine andere Version getestet: Stretch des TImage auf false, AutoSize auf true und dann nicht pImg in Höhe und Breite anpassen, sondern pImg->Picture->Bitmap. Dann stimmt bei verschiedenen Druckerauflösungen die Größe des TImage, aber das enthaltene Bitmap wird zB. beschnitten (bei kleinen Auflösungen), so dass nur die linke obere Ecke des Bitmap gedruckt wird. 😞

    Edit 2: Nach weiterem exessiven Nutzen der Suchfunktion habe ich noch einen Hinweis auf CopyRect gefunden. Damit wird das Bitmap zumindest größenmäßig richtig ausgedruckt. Leider wird bei einer geringen Druckerauflösung das Bitmap sehr pixelig (viel stärker als zu erwarten)... Der pixelige Druck war allerdings überhaupt erst der Grund, warum ich mit Draw anstelle von StretchDraw rumprobiert habe. Mit StretchDraw hatte ich das Bitmap schonmal passend bei verschiedenen Druckerauflösungen, allerdings, wie gesagt, auch pixelig.
    Daher gebe ich jetzt auf und verwende einfach, je nach Druckerauflösung (kann ich ja ermitteln), Bitmaps verschiedener Größen, die ich in ein TImageList-Objekt speichere. Ist zwar nicht schön, da es die Größe meiner Anwendung unnötig aufblät, aber ich kann die Bitmaps ja bei Gelegenheit in eine Ressource packen.
    Die Frage, warum das mit Draw nicht funktioniert, steht, von meinen letzten Ausführungen unberührt, noch im Raum.



  • Der Fehler liegt in Zeile 11.

    *Du skalierst das TImage (richtig)
    *Du belässt das geladen Bitmap im TImage (nicht verkehrt, Bitmap wird ja gestretcht)

    *Du zeichnest das ZU GROSSE Bitmap auf den Drucker!!!

    Da musste schon StrechtDraw nehmen. Oder besser ne Copy- Funktion.

    Gruss
    frank



  • TCanvas *Druckseite= Systemdrucker->Canvas;                                 // Zeiger auf Systemdrucker definieren
    int x= Druckbereichsbreite, y= Druckbereichshöhe;                           // bedruckbarer Bereich in Pixeln
    int Links= int(x * 0.70f), Oben= int(y * 0.055f), Rechts= int(x * 0.88f);   // Werte für Positionierung des Bitmap und für weitere Berechnungen
    TImage *pImg= ImageMitGeladenemBitmap;                                      // Zeiger auf TImage definieren (TImage= 824x236 Pixel & geladenes Bitmap= 824x236 Pixel)
    double Seitenverhältnis= double(pImg->Width) / double(pImg->Height);        // Seitenverhältnis des TImage (und damit auch des Bitmap) berechnen
    int Unten= Oben + int(double(Rechts - Links) / Seitenverhältnis);           // unteren Rand unter Berücksichtigung des Seitenverhältnis berechnen
    pImg->Width= Rechts - Links;                                                // TImage eine neue Breite zuweisen
    pImg->Height= Unten - Oben;                                                 // TImage eine neue Höhe zuweisen => da Stretch= true, sollte das Bitmap im TImage nun die passende Größe haben
    Druckseite->BeginDoc();
    TRect ZielRect(Links, Oben, Rechts, Unten), QuellRect(0, 0, 824, 236);      // NEU
    Druckseite->CopyRect(ZielRect, pImg->Canvas, QuellRect);                    // NEU
    Druckseite->EndDoc();                                                       // Grösse stimmt, aber äußerst pixelig
    pImg->Width= 824;
    pImg->Height= 236;                                                          // ursprüngliche Werte wiederherstellen
    

    Das scheint IMHO zu Nichts zu führen... siehe Edit 2 meines letzten Posts. Was bringt es mir, wenn die Grösse passt, aber das Bild deart entfremdet ist, dass man Nichts erkennen kann... Also muss ich wohl verschieden grosse Bilder für verschiedene Druckerauflösungen hinterlegen!? Oder gibt's Alternativen?

    Edit:
    Das Ganze funktioniert übrigens auch so (eben nur mit pixeligem Ausdruck):

    TCanvas *Druckseite= Systemdrucker->Canvas;                                 // Zeiger auf Systemdrucker definieren
    int x= Druckbereichsbreite, y= Druckbereichshöhe;                           // bedruckbarer Bereich in Pixeln
    int Links= int(x * 0.70f), Oben= int(y * 0.055f), Rechts= int(x * 0.88f);   // Werte für Positionierung des Bitmap und für weitere Berechnungen
    TImage *pImg= ImageMitGeladenemBitmap;                                      // Zeiger auf TImage definieren (TImage= 824x236 Pixel & geladenes Bitmap= 824x236 Pixel)
    double Seitenverhältnis= double(pImg->Width) / double(pImg->Height);        // Seitenverhältnis des TImage (und damit auch des Bitmap) berechnen
    int Unten= Oben + int(double(Rechts - Links) / Seitenverhältnis);           // unteren Rand unter Berücksichtigung des Seitenverhältnis berechnen
    Druckseite->BeginDoc();
    TRect ZielRect(Links, Oben, Rechts, Unten), QuellRect(0, 0, 824, 236);      // NEU
    Druckseite->CopyRect(ZielRect, pImg->Canvas, QuellRect);                    // NEU
    Druckseite->EndDoc();                                                       // Grösse stimmt, aber äußerst pixelig
    


  • Mach mal VOR der Zeiule mit dem CopyRect:

    SetStretchBltMode(DasZielBitmap->Canvas->Handle,HALFTONE);
      SetBrushOrgEx(DasZielBitmap->Canvas->Handle,0,0,NULL);
    

    Als "ZielBitmap" natürlich die richtige Variable bei Dir einfügen.

    Ev. geht das nicht auf dem Drucker- Canvas, dann muss ein TBitmap mit gewünschter Grösse als Puffer für das "Zoomen" her.

    Gruss
    Frank



  • Was meinst du mit Ziel-Bitmap? Drucker->Canvas, also die Zeichenfläche auf der ich die Druckseite erstelle?

    Edit: Hab's grad gelesen in der Hilfe... also Drucker->Canvas!



  • Ohne Erfolg! Ich werd' mir morgen mal über's Netzwerk einen anderen (neueren) Drucker besorgen, ich glaube es liegt an dem viel zu alten Laserdrucker... in PDF-Creator funktioniert es wunderbar mit StretchDraw oder CopyRect!

    Danke für die Betreuung, wieder Einiges gelernt heute 🙂


Log in to reply