Benutzer mit den meisten Antworten
Graphics.DrawString() wie kann ich Buchstaben mittig von A4 Seite positionieren (bzw es berechnen) ?

Frage
-
Hi,
problem ist ich brauche dieses A oder E mittig von der A4 Seite.
e.Graphics.DrawString(cmbKapitel.Text, new Font("Times New Roman", 450), new SolidBrush(Color.Black), new Point(x, y));
Fontgröße ist 450 wie im DrawString.
Das kommt bei new Point(0, 0) raus. (Das bei 0,0 nicht mittig ist, weiss ich. Soll nur ein beispiel sein das bei 0,0 auch nicht wie erwartet raus kommt)
anstelle von(wie erwartet)
Wie kann man die werte berechnen? Für horizontal + vertikal zentriert
- Bearbeitet alex_1978 Mittwoch, 20. April 2016 11:39
Antworten
-
Hallo Alex,
Da spielen viele Dinge eine wichtige Rolle:
- Seitenränder (kann man festlegen, wie genau das geht hängt von der von dir gewählten Print-Klasse ab)
- Skalierung (Auf Monitoren üblicherweise 96 DPI (Dots per Inch), kann man gg. auch festlegen)
- Ggf. Schriftgröße und die zur Schriftart gehörenden Abmessungen. (für vertikales Zentrieren).
BTW, 1pt (Schriftgrößeneinheit) =1/72 Inch
Wenn du auf eine Form das "A" an die Stelle 0|0 zeichnest wird es auch in der Ecke sein. Es sind hier wirklich nur die Druckeinstellungen die Probleme machen.
Um nun Texte zu zentrieren bedarf es der Ermittlung der Stringgröße (siehe Graphics.MeasureString-Methode) und einem Abgleich gegenüber der Größe des A4-Blattes.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Tom Lambert (Koopakiller)Moderator Montag, 25. April 2016 12:49
- Als Antwort markiert Aleksander Chalabashiev Montag, 2. Mai 2016 07:57
-
Oder du erstellst eine Bitmap "On the fly", schreibst den Buchstaben darauf, Crop, Resample auf gewünschte Größe. Dann hasst du exakte Größen und ein Bitmap lässt sich nun präzise positionieren.
HI,
ist zwar möglich, aber der Buchstabe wird dann auf dem bedruckten Blatt möglicherweise nicht so scharf abgebildet, als wäre er im Textmodus gedruckt. (Bseonders, wenn Du tatsächlich resized )
Ich empfehle mittels MeasureCharacterRanges die exakte Größe des Buchstaben zu holen und dann mit den Prontersettings (Margins, dpi, Balttgröße, etc.) die genaue Position zum Drucken zu errechnen.
https://msdn.microsoft.com/de-de/library/system.drawing.graphics.measurecharacterranges%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Viele Grüße,
Thorsten- Bearbeitet Thorsten Gudera Donnerstag, 21. April 2016 11:13
- Als Antwort vorgeschlagen Florian Haupt Montag, 25. April 2016 12:23
- Als Antwort markiert Aleksander Chalabashiev Montag, 2. Mai 2016 07:57
-
Damit könnte ich jetzt noch nicht die realen Größe feststellen. Wie kann man damit jetzt aus der Region auf z.B. die Höhe eines Buchstabens schließen?
...
Ok, ich denke, measureCharacterRanges gibt nur das umschreibende Rechteck zurück. Ist wohl nicht angebracht hier... sorry. Aber hier wird es über den Font gemacht:
https://msdn.microsoft.com/en-us/library/xwf9s90b%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Allerdings auch nur ascent und descent, Vielleicht hilft pInvoke GetGlyphOutline weiter...
Viele Grüße,
Thorsten
- Bearbeitet Thorsten Gudera Freitag, 22. April 2016 17:09
- Als Antwort vorgeschlagen Florian Haupt Montag, 25. April 2016 12:36
- Als Antwort markiert Aleksander Chalabashiev Montag, 2. Mai 2016 07:58
Alle Antworten
-
Hallo Alex,
Da spielen viele Dinge eine wichtige Rolle:
- Seitenränder (kann man festlegen, wie genau das geht hängt von der von dir gewählten Print-Klasse ab)
- Skalierung (Auf Monitoren üblicherweise 96 DPI (Dots per Inch), kann man gg. auch festlegen)
- Ggf. Schriftgröße und die zur Schriftart gehörenden Abmessungen. (für vertikales Zentrieren).
BTW, 1pt (Schriftgrößeneinheit) =1/72 Inch
Wenn du auf eine Form das "A" an die Stelle 0|0 zeichnest wird es auch in der Ecke sein. Es sind hier wirklich nur die Druckeinstellungen die Probleme machen.
Um nun Texte zu zentrieren bedarf es der Ermittlung der Stringgröße (siehe Graphics.MeasureString-Methode) und einem Abgleich gegenüber der Größe des A4-Blattes.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets- Als Antwort vorgeschlagen Tom Lambert (Koopakiller)Moderator Montag, 25. April 2016 12:49
- Als Antwort markiert Aleksander Chalabashiev Montag, 2. Mai 2016 07:57
-
Hallo Alex,
ist jetzt nur mal so eine spontane Idee: Wenn es also darum geht, genau einen großen Buchstaben exakt zentriert auf einem Blatt Papier zu positionieren, könntest du eventuell einfach eine vorgefertigte Grafik/Bitmap verwenden.
Oder du erstellst eine Bitmap "On the fly", schreibst den Buchstaben darauf, Crop, Resample auf gewünschte Größe. Dann hasst du exakte Größen und ein Bitmap lässt sich nun präzise positionieren.
Gruß
-
Oder du erstellst eine Bitmap "On the fly", schreibst den Buchstaben darauf, Crop, Resample auf gewünschte Größe. Dann hasst du exakte Größen und ein Bitmap lässt sich nun präzise positionieren.
HI,
ist zwar möglich, aber der Buchstabe wird dann auf dem bedruckten Blatt möglicherweise nicht so scharf abgebildet, als wäre er im Textmodus gedruckt. (Bseonders, wenn Du tatsächlich resized )
Ich empfehle mittels MeasureCharacterRanges die exakte Größe des Buchstaben zu holen und dann mit den Prontersettings (Margins, dpi, Balttgröße, etc.) die genaue Position zum Drucken zu errechnen.
https://msdn.microsoft.com/de-de/library/system.drawing.graphics.measurecharacterranges%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Viele Grüße,
Thorsten- Bearbeitet Thorsten Gudera Donnerstag, 21. April 2016 11:13
- Als Antwort vorgeschlagen Florian Haupt Montag, 25. April 2016 12:23
- Als Antwort markiert Aleksander Chalabashiev Montag, 2. Mai 2016 07:57
-
- Bearbeitet Klaus Ruttkowski Donnerstag, 21. April 2016 13:25
-
Hallo Thorsten,
ist zwar möglich, aber der Buchstabe wird dann auf dem bedruckten Blatt möglicherweise nicht so scharf abgebildet, als wäre er im Textmodus gedruckt. (Bseonders, wenn Du tatsächlich resized )
Möglicherweise, wenn man es nicht richtig macht... Auf das Resamplen kann man ja ggf. auch verzichten.
Ich empfehle mittels MeasureCharacterRanges die exakte Größe des Buchstaben zu holen und dann mit den Prontersettings (Margins, dpi, Balttgröße, etc.) die genaue Position zum Drucken zu errechnen.
Das interessiert mich jetzt auch: Wie würdest du das mit MeasureCharacterRanges machen? Also nur die Größenbenstimmung des Buchstabens.
Viele Grüße
-
Hallo,
Möglicherweise, wenn man es nicht richtig macht... Auf das Resamplen kann man ja ggf. auch verzichten.
Um es "richtig" zu machen muss man das Bild dynamisch erzeugen. Dann wären wir wieder bei dem ursprünglichen Problem dass es nur darum geht einen Buchstaben zentriert auf ein Graphics zu bekommen.
Das interessiert mich jetzt auch: Wie würdest du das mit MeasureCharacterRanges machen? Also nur die Größenbenstimmung des Buchstabens.
Ich kann nicht für Thorsten sprechen, aber vermutlich würde er es so machen wie im MSDN Artikel gezeigt: Graphics.MeasureCharacterRanges-Methode
In meinen Augen liegt das Hautproblem aber nach wie vor beim Seitenrand.
Bei meiner Lösung über MeasureString wären alle Buchstaben auf gleicher Höhe gewesen, wenn man verschiedene druckt. Einzelne wären dann eventuell nicht zentriert gewesen, nebeneinander gelegt wäre das entstehende Wort aber zentriert gewesen. Wenn es wirklich nur um einen einzelnen Buchstaben geht ist die Benutzung von MeasureCharacterRanges vermutlich die beste.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets -
Das interessiert mich jetzt auch: Wie würdest du das mit MeasureCharacterRanges machen? Also nur die Größenbenstimmung des Buchstabens.
Hi,
siehe z.B.:
https://social.msdn.microsoft.com/Forums/de-DE/e5a40231-410b-4863-bf1a-df49dbf99fd0/measurestring-how-to-find-exact-width-of-string?forum=vbgeneral
Aber trotzdem auch die Margins des Druckers beachten.
Viele Grüße,
Thorsten
-
Hallo Tom,
Um es "richtig" zu machen muss man das Bild dynamisch erzeugen. Dann wären wir wieder bei dem ursprünglichen Problem dass es nur darum geht einen Buchstaben zentriert auf ein Graphics zu bekommen.
klar, das Bitmap kann man eigentlich leicht dynamisch erstellen und auch einen Buchstaben draufmalen. Das "richtig machen" bezog sich auf mögliche Probleme mit der "Schärfe".
Wenn man das Bitmap dann freistellt, berührt der Buchstabe alle Ränder des Bitmaps und man ermittelt in der Tat eine exakte Höhe und Breite. Das sehe ich bei der vorgeschlagenen Methode... (noch) nicht.
Ich kann nicht für Thorsten sprechen, aber vermutlich würde er es so machen wie im MSDN Artikel gezeigt: Graphics.MeasureCharacterRanges-Methode
Wenn ich das Beispiel versuche nachzuvollziehen, erhalte ich solche Ergebnisse:
Times New Roman:
Segoe UI:
Damit könnte ich jetzt noch nicht die realen Größe feststellen. Wie kann man damit jetzt aus der Region auf z.B. die Höhe eines Buchstabens schließen?
Das Problem mit den Seitenrändern ist ja sicherlich etwas, was man durch ein-zwei Probedrucke für jeweils einen spezifischen Drucker lösen kann.
Gruß
-
Hallo K. Pater,
Das "richtig machen" bezog sich auf mögliche Probleme mit der "Schärfe".
Ich wollte ursprünglich darauf hinaus das der Umweg über eine Bitmap nichts bringt. Man zeichnet ja so oder so auf ein Graphics-Objekt. Das bezog sich allerdings auf die Annahme dass MeasureCharacterRanges etwas anders arbeitet.
Wenn ich das Beispiel versuche nachzuvollziehen, erhalte ich solche Ergebnisse[...]
Ich habe die Doku so verstanden dass man wirklich die Kanten der jeweiligen Buchstaben erhält. Gut, dann habe ich mir hier getäuscht. So wie es für mich aussieht gibt die Methode den Bereich zurück der mit Akzenten ausgefüllt wird, bis zu den Grenzen an denen der nächste Buchstabe beginnt. Somit wären auch die Überlappungen erklärbar.
Dann würde ich vermutlich doch bei MeasureString bleiben oder aber mich nach einer anderen Lösung umsehen. Am elegantesten könnte man es vermutlich mittels DirectWrite lösen (habe ich bisher nur in UWP Apps verwendet). Das ist allerdings mit Kanonen auf Spatzen geschossen wenn der TE das alles gar nicht so genau zentriert braucht.
Das Problem mit den Seitenrändern ist ja sicherlich etwas, was man durch ein-zwei Probedrucke für jeweils einen spezifischen Drucker lösen kann.
Das sollte eigentlich unnötig sein. Standardmäßig sind bei den meisten Druckerklassen Seitenränder eingestellt. (Welche ist es denn eigentlich?) Diese muss man nur auf 0 setzen. Dann druckt man wirklich am äußersten Rand los. Man muss dann nur immer im Hinterkopf behalten, dass die Ränder zwar gerendert, aber von den meisten Druckern nicht gedruckt werden.
Nachtrag: Das Problem an MeasureCharacterRanges ist, dass Schrift nicht so einfach ist wie die meisten sie sich vorstellen. Einzelne Buchstaben können ihre Bereiche überlappen lassen und Sonderfälle wie Ligaturen gibt es auch noch. Deswegen funktioniert die Methode scheinbar gut in größeren Strings, aber auch immer nur solange wie die benachbarten Zeichen sich nicht mit dem gemessenen Verbinden. Da wir hier aber nur einzelne Zeichen haben ist wieder mal zunächst zu klären was denn "zentriert" genau meint.
Zentrieren würde ich so verstehen dass man die "große" Box um den String herum nutzt wie sie MeasureString zurück gibt. Und diese enthält nun mal all die Sonderfälle wie Akzente usw. womit bei mehreren gedruckten Buchstaben auf mehreren Blättern am Ende alle zusammen ein einheitliches Schriftbild haben obwohl die wenigsten davon zentriert sind.
Tom Lambert - .NET (C#) MVP
Wozu Antworten markieren und für Beiträge abstimmen? Klicke hier.
Nützliche Links: .NET Quellcode | C# ↔ VB.NET Konverter | Account bestätigen (Verify Your Account)
Ich: Webseite | Code Beispiele | Facebook | Twitter | Snippets
- Bearbeitet Tom Lambert (Koopakiller)Moderator Freitag, 22. April 2016 16:57 Nachtrag
-
Damit könnte ich jetzt noch nicht die realen Größe feststellen. Wie kann man damit jetzt aus der Region auf z.B. die Höhe eines Buchstabens schließen?
...
Ok, ich denke, measureCharacterRanges gibt nur das umschreibende Rechteck zurück. Ist wohl nicht angebracht hier... sorry. Aber hier wird es über den Font gemacht:
https://msdn.microsoft.com/en-us/library/xwf9s90b%28v=vs.110%29.aspx?f=255&MSPPError=-2147217396
Allerdings auch nur ascent und descent, Vielleicht hilft pInvoke GetGlyphOutline weiter...
Viele Grüße,
Thorsten
- Bearbeitet Thorsten Gudera Freitag, 22. April 2016 17:09
- Als Antwort vorgeschlagen Florian Haupt Montag, 25. April 2016 12:36
- Als Antwort markiert Aleksander Chalabashiev Montag, 2. Mai 2016 07:58
-
Ok, ich denke, measureCharacterRanges gibt nur das umschreibende Rechteck zurück. Ist wohl nicht angebracht hier... sorry. Aber hier wird es über den Font gemacht:
Und dieses Rechteck reicht vollkommen aus um damit die nötige Koodinate für das Zeichnen zu berechnen. Die Möglichkeit über den Font ist eine gute Alternative und führt auch zum Ziel, rechnen muss man trotzdem.
Genauso wie die Printersettings reichen um den Mittelpunkt des Blattes zu berechnen.
- Florian