用RotateTransform绕其中心旋转文本

6

我有这样一段C#代码来绘制旋转文本:

        Font font = new Font("Arial", 80, FontStyle.Bold);
        int nWidth = pictureBox1.Image.Width;
        int nHeight = pictureBox1.Image.Height;

        Graphics g = Graphics.FromImage(pictureBox1.Image);

        float w = nWidth / 2;
        float h = nHeight / 2;

        g.TranslateTransform(w, h);
        g.RotateTransform(90);

        PointF drawPoint = new PointF(w, h);
        g.DrawString("Hello world", font, Brushes.White, drawPoint);

        Image myImage=new Bitmap(pictureBox1.Image); 

        g.DrawImage(myImage, new Point(0, 0));

        pictureBox1.Image = myImage;
        pictureBox1.Refresh();

如果不进行旋转,文本将绘制在图像中心,但使用RotateTransform后,文本会超出图像的一半,并且旋转中心偏离。

如何仅围绕其中心旋转文本?而不影响文本在图像上的位置。


请看这个答案:https://dev59.com/Bm855IYBdhLWcg3wUCaC - aybe
谢谢,但对我来说不起作用,因为我将文本放在一张大图像上。因此,图像比文本要大得多。 - Mario
3个回答

7

如果您想在图像中心绘制旋转的文本,则需要将文本位置的偏移量设置为文本大小的一半:

using (Font font = new Font("Arial", 80, FontStyle.Bold))
using (Graphics g = Graphics.FromImage(pictureBox1.Image))
{
    float w = pictureBox1.Image.Width / 2f;
    float h = pictureBox1.Image.Height / 2f;

    g.TranslateTransform(w, h);
    g.RotateTransform(90);

    SizeF size = g.MeasureString("Hello world", font);
    PointF drawPoint = new PointF(-size.Width / 2f, -size.Height / 2f);
    g.DrawString("Hello world", font, Brushes.White, drawPoint);
}

pictureBox1.Refresh();

(在使用完FontGraphics对象后进行处理是个好主意,因此我添加了一些using语句。)

变化 #1:这段代码将文本的左上角位置设置为(400,200),然后围绕该点旋转文本:

g.TranslateTransform(400, 200);
g.RotateTransform(90);
PointF drawPoint = new PointF(0, 0);
g.DrawString("Hello world", font, Brushes.White, drawPoint);

变化 #2: 这个片段将文本的左上角定位在 (400, 200),然后围绕文本中心旋转文本:

SizeF size = g.MeasureString("Hello world", font);
g.TranslateTransform(400 + size.Width / 2, 200 + size.Height / 2);
g.RotateTransform(90);
PointF drawPoint = new PointF(-size.Width / 2, -size.Height / 2);
g.DrawString("Hello world", font, Brushes.White, drawPoint);

如果文本被放置在图像的中央,那么这似乎是有效的,但是如果用户将文本放置在图像的自定义位置,我该怎么办?那么我又该如何计算旋转角度呢?比如在 x=400 和 y=200 的位置。 - Mario
@MarioM:您的意思是在文本旋转时,希望文本的左上角固定在x=400,y=200吗?(如果不是左上角,那么应该围绕哪个点旋转文本?) - Michael Liu
也许您可以草拟一张图,显示背景图像的边界、点 (400, 200) 的位置以及 "Hello world" 相对于该点的位置和方向。 - Michael Liu
非常感谢!变体#1就是我需要的。 - Mario

1
当你进行翻译时,你已经处于中心位置,因此不应该在该位置的偏移量处绘制文本。
float w = ClientRectangle.Width / 2-50;
float h = ClientRectangle.Height / 2-50;
g.TranslateTransform(w, h);
g.RotateTransform(angle);
PointF drawPoint = new PointF(0, 0);
g.DrawString("Hello world", font, brush, drawPoint);

你的代码不起作用,我已经更新了问题,使其更加简单。 - Mario
代码运行良好,只是其中某一部分出现了问题。尝试将 PointF drawPoint = new PointF(w, h); 更改为 PointF drawPoint = new PointF(0, 0); 然后重新运行。至少在我的机器上,您发布的代码从中间开始向下运行图像。我在这个链接上发布了一个截图。 - Torgrim Brochmann
不,文本不应该从中间开始向下,而应该像螺旋桨一样围绕其中心旋转。 - Mario

0

如何在GDI+中旋转文本?可以实现,但您需要在一个坐标平面上旋转文本块,该平面的宽度和高度都等于文本块的最长尺寸。该坐标平面应该以文本框的中心为中心。

如果您的坐标平面背景图像,则无法正常工作。请注意我更改了PointF的值:

grPhoto.DrawString(m_Copyright,                 //string of text
                crFont,                         //font
                myBrush,                        //Brush
                new PointF(xCenterOfText, yPosFromBottomOfText),  //Position
                StrFormat);                               //Text alignment

旋转图像与旋转矩阵是相同的:

http://en.wikipedia.org/wiki/Rotation_matrix


如果文本块靠近图像边缘,则无法在旋转块时保持其中心。 如果您的文本块宽度为100像素,距离边缘30像素,则当您将其旋转π/2弧度时,20像素将在图像外部。 您别无选择,只能重新居中它。 - JaneGoodall
那么,看来我需要重新计算中心的方法。 - Mario

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接