Ich möchte eine selbstgezeichnete Grafik auf eine A4 Seite anpassen und ausdrucken
Wenn die Grafik über das Maß hinaus geht, soll sie verkleinert werden, ansonsten soll die Größe übernommen werden.
Zum Skalieren der Grafik benutze ich die Graphics.DrawImage() Methode.
Dabei entsteht die unerwünschte Verzehrung, die Linien unterschiedlich dick darstellt, siehe Dateianhang.
// VERZEHRUNG
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
using (Bitmap b = new Bitmap(_grid.Width, _grid.Height))
{
using (Graphics g = Graphics.FromImage(b))
{
_grid.Paint(g);
e.Graphics.DrawImage(b, 0, 0);
// e.Graphics.DrawImage(b, 0, 0, 400, 400);
b.Save(_path, System.Drawing.Imaging.ImageFormat.Png);
}
}
}
// KEINE VERZEHRUNG
private void printDocument1_PrintPage(object sender, System.Drawing.Printing.PrintPageEventArgs e)
{
_grid.Paint(e.Graphics);
}
Erst dachte ich, es läge am Bitmap-Objekt und habe jene Grafik ohne optische Probleme abgespeichert, siehe Dateianhang.
Im Anschluss kommentierte ich jene DrawImage() Zeile aus und versuchte - ohne die Breite und Höhe zu verändern - die Grafik 1:1 an das Drucker-Ereignis weiterzuleiten, mit entsprechenden Erfolgen, siehe Code.
Meines Erachtens liegt mein Problem an der DrawImage() Methode selbst.
Welche Alternative bzw. Herangehensweise gäbe es dazu?
Der auskommentierte Code zeichnet das Bild mit Höhe und Breite 400, soll das so sein? Falls es nicht quadratisch ist wird es dadurch verzerrt. (Mahlzeit *g* )
Von der Vorgabe "wenn größer soll es verkleinert werden" ist in deinem Code nichts zu sehen.
Dieser Beitrag wurde 2 mal editiert, zum letzten Mal von chilic am .
//zeigt die dünneren Linien etwas besser an
Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
// Beide Methoden führen zu einer Verzehrung
Graphics.DrawImage(bmp, 0, 0);
Graphics.DrawImageUnscaled(bmp, 0, 0);
Als letzten Ausweg sehe ich eine zweite Paint-Methode zu schreiben, die einen Skalierfaktor beinhaltet.
Damit sollte es angemessen erscheinen, siehe Dateianhang.
GDI+ war nie konzipiert, dass das 1:1 in den Drucker geht, egal ob nun GDI+ via .NET oder C++ oder oder oder...
Der beste Built-In Weg wird wohl immer noch das PrintDocument sein.
Ansonsten muss man schon sagen, dass die Drittanbieter-Angebote, vor allem bei komplexeren Dingen, in diesem Fall schon ihre Daseinsberechtigung haben.
PS: Es heisst verzerren / verzerrt. Verzehren komm von Essen, dass man etwas isst.
Ich habs im Titel korrigiert, sodass man das Thema wenigstens mit der korrekten Schreibweise über die Suche findet.
wie lustig, dass mir das "Verzehren" nicht aufgefallen ist. Danke!
Externe Funktionen wie StretchBlt() und TransparentBlt() skalieren optisch ansprechender als Graphics.DrawImage(), ABER ... es mogelt sich ein grauer Hintergrund (RGB[211,211,211]) hinzu, den ich nicht wegbekomme.
Die Klasse Grid ist noch kein Control, vielmehr eine Testklasse für ein übergeordnetes Projekt, das auf ein Control hinauslaufen wird.
Es beinhaltet auch eine BackColor-Eigenschaft, die die Hintergrundfarbe des darunterliegenden Parent-Controls setzt.
Also habe ich folgendes versucht:
Wenn ich das richtig sehe wird erst eine Bitmap erstellt, welche dann auf das PrintDocument gezeichnet wird.
Warum der Umweg über das Bitmap und nicht direkt auf e.Graphics zeichnen?
PrintPageEventArgs bietet doch die Eigenschaften für die Seitengröße.
Diese musst Du entsprechende verwenden und umrechnen, für das Zeichnen der Linien.
Eine Bitmap hat eine andere DPI z.B. 96, als ein Drucker (z.B. 300 oder 600).
Wie könnte mir das Ändern der Seitengröße hier weiterhelfen?
Zitat von Abt
Zu den Grundlagen/Unterschieden zwischen Drucker DPI und Bildschirm / Grafik "DPI" siehe mein Beitrag in Maßstabsgetreu zeichnen und drucken
Mit dem Umrechnen von DPI in Zentimeter oder umgekehrt komm ich durchaus auf ein vernünftiges Druckergebnis.
Das gilt sowohl für den virtuellen XPS- als auch für meine HP-Drucker.