I'm using the following code to draw inclined text all over an image. This works, but not as intended.
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;
This is the result of the code
What I'm, looking for is something like the image below. You can see there are multiple lines of text in the same line. How would I set the font size of the text so that the image is watermarked properly.
I used Jen's explanation to find the bounding box of the rotated text.
I start in the top left of the bitmap and start drawing a diagonal line of repeating text going up and to the right. Each time the line goes off the right or top edge, I start a new diagonal line by adding twice the total height of the line. As I draw each diagonal line of text, I track whether one of the starting coords is within the bounds of the bitmap. When I find an entire line that didn't cross the bitmap then I know we're done.
*Oh, I see your Leo DiCaprio and up you with a 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.
Modified code to handle both directions.
Note the two different calls to Watermark()
with parameters:
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();
}
Sample output: