Texte und Bilder drehen
-
Ich zeichne Texte und Bilder auf ein Graphics-Objekt mit den Funktionen DrawString und DrawImage. Wie kann ich die Bild- und Textobjekte jetzt individuell drehen?
Es gibt zwar die Methode RotateTransform, aber die verändert irgendwie das komplette Koordinatensystem.
Ich brauche das aber so, dass wenn ein Text vorher an Position 5;0 stand, dass der um 45° gedrehte Text immer noch an Position 5;0 steht.Beispiel:
Das ist die Ausgangsposition mit dem Text "ABC" an Position 5;0:
+----------------+ | ABC | | | | | | | +----------------+
Das ist die Situation, die ich brauche, bei der der Text um 45° gedreht ist (die Buchstaben wären dann natürlich auch gedreht, das hier ist nur eine vereinfachte Darstellung):
+----------------+ | A | | B | | C | | | +----------------+
Aber mit der Funktion RotateTransform scheint er irgendwie das ganze "Blatt" zu drehen und das kommt dabei raus:
+----------------+ | | | A | | B | | C | +----------------+
Was muss ich machen, damit ich ein einzelnes Text- oder Bildelement auf einem Graphics-Objekt drehen kann, wobei die Ausgangsposition erhalten bleibt?
-
Sieh dir z.B.
Matrix.RotateAt
an.Grüssli
-
Mit der Funktion gibt's bei mir im Moment noch einige Probleme.
Der Text wird nicht mehr sauber angezeigt, sondern total unordentlich dahingekrakelt.
Und es besteht immer noch das Problem, dass er die Position nicht vernünftig berechnet. Er verschiebt den Text dann immer noch wie in meinem dritten Beispielbild.
-
Keiner eine Idee?
-
Du rotierst ja auch um den Ursprung.
1. Text in Ursprung verschieben
2. Rotieren
3. Text zurückschieben
-
Jedermann schrieb:
Mit der Funktion gibt's bei mir im Moment noch einige Probleme.
Der Text wird nicht mehr sauber angezeigt, sondern total unordentlich dahingekrakelt.
Und es besteht immer noch das Problem, dass er die Position nicht vernünftig berechnet. Er verschiebt den Text dann immer noch wie in meinem dritten Beispielbild.Dann machst du irgendetwas falsch. Bei mir funktioniert dies problemlos:
http://i48.tinypic.com/2i7l9c4.pngIch habe einfach ein
Form
genommen, darin einPanel
platziert und das Paint-Event abonniert.using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace FormsTest { public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void OnPanelPaint(object sender, PaintEventArgs e) { var g = e.Graphics; var matrix = new Matrix(); matrix.RotateAt(30.0f, new PointF(20, 20)); g.Transform = matrix; g.DrawString("Hello World!", new Font("Calibri", 12.0f), Brushes.Black, 20, 20); } } }
Grüssli
-
Danke. Ja, so funktioniert's. Irgendwas hab ich wirklich falsch gemacht.
Noch etwas: Im Moment wird ja quasi an der linken oberen Ecke gedreht. Das heißt, wenn ich ein Bild um 90° drehe, dann ist die Position des alten linken Rands jetzt die Position des neuen rechten Rands. Also ungefähr so, als wenn ich oben links einen Nagel in das Bild haue und an diesem wird dann gedreht.
Wie krieg ich es hin, dass auch in der gedrehten Fassung der oberste linke Punkt an derselben Position liegt wie der oberste linke Punkt des nicht gedrehten Objekts?Zur Veranschaulichung
Ungedreht (Bild ist an Position 3;0):
+--------+ | #### | | #### | | | | | | | +--------+
Gedreht (Bild ist an Position 1;0, weil Position 3;0 der Drehpunkt ist):
+--------+ | ## | | ## | | ## | | ## | | | +--------+
So wie ich es brauche (Bild ist auch in der gedrehten Fassung an Position 3;0:
+--------+ | ## | | ## | | ## | | ## | | | +--------+
Also er soll das Bild drehen, aber dann soll er den aktuellen Ursprungspunkt des Bildes bzw. des Textes wieder an die Stelle setzen, wo vorher der Ursprungspunkt war. Wie kann ich das berechnen?
-
Jedermann schrieb:
Wie kann ich das berechnen?
Füg eine entsprechende Translation hinzu. Wenn du um 90° drehst, entspricht dies dann genau der Höhe des Bildes.
http://i49.tinypic.com/23igv9y.png
using System.Net; using System.Drawing; using System.Drawing.Drawing2D; using System.Windows.Forms; namespace FormsTest { public partial class Form1 : Form { private readonly Image m_image; public Form1() { InitializeComponent(); var request = WebRequest.Create("http://i48.tinypic.com/2i7l9c4.png"); using(var response = request.GetResponse()) { m_image = Image.FromStream(response.GetResponseStream()); } } private void OnPanelPaint(object sender, PaintEventArgs e) { var g = e.Graphics; var matrix = new Matrix(); matrix.Translate(m_image.Height, 0); matrix.RotateAt(90.0f, new PointF(20, 20)); g.Transform = matrix; g.DrawImage(m_image, 20, 20); } } }
Ich weiss nicht, wie genau du dich mit Matrizen auskennst. Man kann verschiedene Projektionen über Matrizen beschreiben. Wenn man sie miteinander multipliziert, entspricht dies der Anwendung der jeweiligen Projektion in umgekehrter Reihenfolge zur Multiplikation.
Wenn du mein Beispiel anschaust, wende ich zuerst einTranslate
und danach einRotateAt
an. Tatsächlich wird dies beim Output dazu führen, dass zuerst einRotateAt
und danach einTranslate
durchgeführt wird.Wenn du mehr dazu wissen willst, informier dich über Matrizen im Bereich von Computergraphiken.
Grüssli