在位图上绘制对角线文本
Posted
技术标签:
【中文标题】在位图上绘制对角线文本【英文标题】:Drawing Diagonal Text all over Bitmap 【发布时间】:2022-01-15 17:09:18 【问题描述】:我正在使用以下代码在整个图像上绘制倾斜的文本。这可以工作,但不是预期的。
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;
这是代码的结果
我正在寻找类似于下图的内容,您可以看到同一行中有多行文本。另外,您将如何确定文本的字体大小,以便正确地为图像添加水印.
【问题讨论】:
【参考方案1】:我使用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();
样本输出:
【讨论】:
非常感谢您的努力。这很好:) 我有另一个问题。当我尝试将文本的方向更改为 -from top left to bottom right
使用45
而不是 -45
角度,我在图像的左侧看到了一个间隙。请参阅imgur.com/a/svxodFz
我将从我的工作计算机发布更新。
谢谢 .... ....
查看修改后的帖子和代码。
非常感谢...以上是关于在位图上绘制对角线文本的主要内容,如果未能解决你的问题,请参考以下文章