在整个位图上绘制对角线文本

Drawing Diagonal Text all over Bitmap

我正在使用以下代码在整个 image.This 作品中绘制倾斜的文本,但不是预期的那样。

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;

这是代码的结果

我正在寻找的是像下图这样的东西,正如您所看到的,在同一个 line.Also 中有多行文本 line.Also 您如何确定文本的字体大小,以便图片已正确加水印。

我使用 Jen's explanation 找到旋转文本的边界框。

我从位图的左上角开始绘制一条由重复文本组成的对角线,向上和向右。每次该线离开右边缘或上边缘时,我都会通过添加该线总高度的两倍来开始一条新的对角线。当我绘制文本的每条对角线时,我跟踪其中一个起始坐标是否在位图的边界内。当我找到没有穿过位图的整条线时,我就知道我们完成了。

*哦,我看到了你的 Leo DiCaprio 和 Chris Hemsworth。

When i try to change the direction of the text from top left to bottom right using 45 instead of -45 angle, i see a gap in the left portion of the image.

修改代码以处理两个方向。

请注意对 Watermark() 的两次不同调用,参数为:

private void button1_Click(object sender, EventArgs e)
{
    Watermark(pictureBox1, WatermarkDirection.BottomLeftToTopRight, "Do not copy!");
    Watermark(pictureBox2, WatermarkDirection.TopLeftToBottomRight, "Proof");
}

enum WatermarkDirection
{
    BottomLeftToTopRight,
    TopLeftToBottomRight
    
}

private void Watermark(PictureBox pb, WatermarkDirection direction, String text)
{
    Bitmap bmp = new Bitmap(pb.Image);
    Rectangle rcBmp = new Rectangle(new Point(0, 0), bmp.Size);
    Graphics g = Graphics.FromImage(bmp);
    Font font = new Font(DefaultFont.Name, 20);
    SizeF size = g.MeasureString(text, font);
    int textwidth = (int)size.Width;
    int textheight = (int)size.Height;

    int angle = (direction == WatermarkDirection.BottomLeftToTopRight) ? -45 : 45;
    int y_main = Math.Abs((int)(textwidth * Math.Sin(angle * Math.PI / 180.0)));
    int x_main = Math.Abs((int)(textwidth * Math.Cos(angle * Math.PI / 180.0)));
    int y_add = Math.Abs((int)(textheight * Math.Cos(angle * Math.PI / 180.0)));
    int x_add = Math.Abs((int)(textheight * Math.Sin(angle * Math.PI / 180.0)));
    int totalX = x_main + x_add;
    int totalY = y_main + y_add;

    // keep going down until we find a line that doesn't cross our bmp
    Rectangle rcText;
    bool intersected = true;
    int multiplier = (direction == WatermarkDirection.BottomLeftToTopRight) ? 1 : -1;
    int offset = (direction == WatermarkDirection.BottomLeftToTopRight) ? -totalY : 0;            
    for (int startY = totalY; intersected; startY += (2 * totalY))
    {
        intersected = false;
        int x = (direction == WatermarkDirection.BottomLeftToTopRight) ? 0 : (bmp.Width - totalX);
        int y = startY;
           
        rcText = new Rectangle(new Point(x, y + offset), new Size(totalX, totalY));
        if (rcBmp.IntersectsWith(rcText)) { intersected = true; }
        while (((direction == WatermarkDirection.BottomLeftToTopRight) && (x <= bmp.Width || y >= 0)) ||
                ((direction == WatermarkDirection.TopLeftToBottomRight) && (x >=0 || y >= 0)))
        {                    
            g.TranslateTransform(x, y);
            g.RotateTransform(angle);
            g.DrawString(text, font, Brushes.Yellow, 0, 0);
            g.ResetTransform();
            
            x += (totalX * multiplier);
            y -= totalY;
            rcText = new Rectangle(new Point(x, y + offset), new Size(totalX, totalY));
            if (rcBmp.IntersectsWith(rcText)) { intersected = true; }
        }
    }
    pb.Image = bmp;
    g.Dispose();
    font.Dispose();
}

示例输出: