在图像上以角度平铺文本

3
我使用以下代码在图像的中心位置以一定角度绘制文本。
Bitmap bmp = new Bitmap(pictureBox1.Image);
using (Graphics g = Graphics.FromImage(bmp)) {
  g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);
  g.RotateTransform(30);
  SizeF textSize = g.MeasureString("hi", font);
  g.DrawString("hi", font, Brushes.Red, -(textSize.Width / 2), -(textSize.Height / 2));
}

我需要将文本像这样铺满整张图片:

enter image description here

我知道可以增加坐标并使用循环来实现。
Bitmap bmp = new Bitmap(pictureBox1.Image);
            for (int i = 0; i < bmp.Width; i += 20)
            {
                for (int y = 0; y < bmp.Height; y += 20)
                {
                    using (Graphics g = Graphics.FromImage(bmp))
                    {
                        g.TranslateTransform(bmp.Width / 2, bmp.Height / 2);                      
                        g.RotateTransform(30);
                        SizeF textSize = g.MeasureString("my test image", DefaultFont);
                        g.DrawString("my test image", DefaultFont, Brushes.Yellow, i, y);
                       
                    }
                }
            }
            pictureBox1.Image = bmp;

这将产生以下结果

enter image description here

如何通过准确测量绘制区域来正确地放置文本,也许有更好、更快的方法。


你是每次都添加相同的文本还是有动态变化的? - Ňɏssa Pøngjǣrdenlarp
2个回答

2

调用额外的TranslateTransform,将文本移动到所需位置,然后使用DrawString在(0,0)坐标处绘制文本。这将使每个文本围绕其自身中心旋转,而不是围绕段落中心旋转文本。

Bitmap bmp = new Bitmap(pictureBox1.Image);
Graphics g = Graphics.FromImage(bmp);
String text = "TextTile";

Font font = new Font(DefaultFont.Name, 20);
SizeF size = g.MeasureString(text, font);
int textwidth = size.ToSize().Width;
int textheight = size.ToSize().Height;

int y_offset = (int)(textwidth * Math.Sin(45 * Math.PI / 180.0));

//the sin of the angle may return zero or negative value, 
//it won't work with this formula
if (y_offset >= 0)
{
    for (int x = 0; x < bmp.Width; x += textwidth)
    {
        for (int y = 0; y < bmp.Height; y += y_offset)
        {
            //move to this position
            g.TranslateTransform(x, y);

            //draw text rotated around its center
            g.TranslateTransform(textwidth, textheight);
            g.RotateTransform(-45);
            g.TranslateTransform(-textwidth, -textheight);
            g.DrawString(text, font, Brushes.Yellow, 0, 0);

            //reset
            g.ResetTransform();
        }
    }
}

pictureBox1.Image = bmp;

上面的例子使用了大小为20的较大字体。您可以将其设置回使用DefaultFont.size。它使用45度角度。

非常感谢,它运行良好。如果图像很大,我在想这种方法的性能如何。在位图上绘制文本并将该位图绘制到整个图像上是否是更好的方法? - techno
你应该自动拥有双缓冲。上面的代码应该在内存中准备图像并仅绘制一次。主要瓶颈是当图像在屏幕上绘制时,或者当像素在屏幕上改变时。顺便说一下,最后一行不是必需的:pictureBox1.Image = bmp; 或者,您可以将picturebox图像保留为none,然后在运行时加载图像并进行绘制,最后设置 pictureBox1.Image = bmp; 在结尾处。 - Barmak Shemirani

1
您正在将文本插入页面中心。
这意味着您的图像0,0坐标位于另一张图像的50%,50%处。
如果您想获得所需的结果,我建议您将图像宽度分成25%的块,以获得建议的16个块。然后在每个块的中心添加其中一个文本图像。
请记住,当您添加图像并希望从点而不是从原点0,0(这是您的情况)旋转图像时,您需要明确说明,命令类似于rotateorigan

你能发布实现代码吗? - techno

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