我使用Jen's explanation 找到旋转文本的边界框。
我从位图的左上角开始绘制一条向上和向右的重复文本的对角线。每次线离开右侧或顶部边缘时,我都会通过添加线总高度的两倍来开始一条新的对角线。当我绘制文本的每条对角线时,我会跟踪其中一个起始坐标是否在位图的范围内。当我找到一条没有穿过位图的整条线时,我就知道我们已经完成了。
*哦,我看到了你的 Leo DiCaprio 和 Chris Hemsworth。
当我尝试将文本的方向从左上角更改为底部时
右使用 45 而不是 -45 角度,我看到左侧有一个间隙
图片。
修改代码以处理两个方向。
注意对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();
}
样本输出: