Aurigma Forums
»
Graphics Mill
»
Discussions – Graphics Mill
»
Write Curved text on an existing image around the round edge
Rank: Newbie
Groups: Member
Joined: 12/2/2010(UTC) Posts: 4
Thanks: 1 times
|
Hi there, Many thanks for your earlier replies and as per your request I got new image created without Alpha mode so I am able to write on it using GdiGraphics. But now the problem I am facing is writing around the edge of inner circle. Please refer to the attached images: Source - Source image file. Destination - Destination image file after running the code. Also the code I wrote is as following: Code:
private void button1_Click(object sender, EventArgs e)
{
try {
const int centerX = 80;
const int centerY = 125;
const int radius = 95;
//Create Bitmap object
Aurigma.GraphicsMill.Bitmap bitmap =
new Aurigma.GraphicsMill.Bitmap(135, 135, Aurigma.GraphicsMill.PixelFormat.Format24bppRgb);
bitmap.Load(@"C:\Temp\Test.png");
Aurigma.GraphicsMill.Drawing.GdiGraphics graphics = bitmap.GetGdiGraphics();
//Adjust font settings
Aurigma.GraphicsMill.Drawing.Font font =
new Aurigma.GraphicsMill.Drawing.Font("Arial",10, false, false);
font.VerticalAlignment = Aurigma.GraphicsMill.Drawing.VerticalAlignment.Bottom;
font.HorizontalAlignment = Aurigma.GraphicsMill.Drawing.HorizontalAlignment.Center;
string text = "Rounded sample text";
//Get characters positions
float[] positions = font.GetCharacterPositions(text, 0);
//Get string width
float strWidth = font.MeasureString(text).Width;
//Get string height
float strHeight = font.MeasureString(text).Height;
Aurigma.GraphicsMill.Drawing.SolidBrush brush =
new Aurigma.GraphicsMill.Drawing.SolidBrush(Aurigma.GraphicsMill.RgbColor.Black);
//Draw character by character
for (int i = 0; i < text.Length; i++)
{
float charWidth = font.GetBlackBox(text[i]).Width;
//Compute angle to which rotate current character. Rotation will be
//performed relative to the middle of the bottom side of the character.
float angle = (float)(Math.PI - (positions[i] + charWidth / 2.0f) * Math.PI / strWidth);
//Compute the x and y coordinate of the bottom/top* middle* of the character
float x = (float)(centerX + radius * Math.Cos(angle));
float y = (float)(centerY - radius * Math.Sin(angle));
System.Drawing.Drawing2D.Matrix rotateMatrix = new System.Drawing.Drawing2D.Matrix();
//Convert angle from radians to degrees
float degAngle = (float)(angle / Math.PI * 180 + 100);
rotateMatrix.RotateAt(90 - degAngle, new System.Drawing.PointF(x, y));
graphics.Transform = rotateMatrix;
graphics.DrawString(text[i].ToString(), font, brush, x, y);
}
bitmap.Save(@"C:\Temp\NewImage.png");
MessageBox.Show("done");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
I am planning to buy your control if it allows to write curved text on the upper part and lower part properly around the inner circle. And based on the examples on your website, it should be able to do it. I am sure, I'm missing something or wrote the buggy code. Are you able to look into my code or provide me the code that writes around the edge of the inner circle. Many thanks in advance and look forward to your reply. Regards. SteveH attached the following image(s):
|
|
|
|
Rank: Advanced Member
Groups: Member
Joined: 5/29/2010(UTC) Posts: 1,310
Thanks: 8 times Was thanked: 111 time(s) in 111 post(s)
|
Hello Frank, I corrected your code, and listed it below. Please look through it. This code allows adding the round text on upper part of your PNG file: Code:
const int centerX = 67;
const int centerY = 68;
const int radius = 42;
//Create Bitmap object
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(134, 135, Aurigma.GraphicsMill.PixelFormat.Format24bppRgb);
bitmap.Load(@"C:\Temp\test.png");
Aurigma.GraphicsMill.Drawing.GdiGraphics graphics = bitmap.GetGdiGraphics();
//Adjust font settings
Aurigma.GraphicsMill.Drawing.Font font = new Aurigma.GraphicsMill.Drawing.Font("Arial", 12, false, false);
font.VerticalAlignment = Aurigma.GraphicsMill.Drawing.VerticalAlignment.Bottom;
font.HorizontalAlignment = Aurigma.GraphicsMill.Drawing.HorizontalAlignment.Center;
string text = "Rounded sample text";
//Get characters positions
float[] positions = font.GetCharacterPositions(text, 0);
//Get string width
float strWidth = font.MeasureString(text).Width;
//Get string height
float strHeight = font.MeasureString(text).Height;
Aurigma.GraphicsMill.Drawing.SolidBrush brush = new Aurigma.GraphicsMill.Drawing.SolidBrush(Aurigma.GraphicsMill.RgbColor.Black);
//Draw character by character
for (int i = 0; i < text.Length; i++)
{
float charWidth = font.GetBlackBox(text[i]).Width;
//Compute angle to which rotate current character. Rotation will be
//performed relative to the middle of the bottom side of the character.
float angle = (float)(Math.PI - (positions[i] + charWidth / 2.0f) * Math.PI / strWidth);
//Compute the x and y coordinate of the bottom/top* middle* of the character
float x = (float)(centerX + radius * Math.Cos(angle));
float y = (float)(centerY - radius * Math.Sin(angle));
System.Drawing.Drawing2D.Matrix rotateMatrix = new System.Drawing.Drawing2D.Matrix();
//Convert angle from radians to degrees
float degAngle = (float)(angle / Math.PI * 180);
rotateMatrix.RotateAt(90 - degAngle, new System.Drawing.PointF(x, y));
graphics.Transform = rotateMatrix;
graphics.DrawString(text[i].ToString(), font, brush, x, y);
}
bitmap.Save(@"C:\Temp\NewImage.png");
This one adds round text on the lower part of image: Code:
const int centerX = 67;
const int centerY = 68;
const int radius = 42;
//Create Bitmap object
Aurigma.GraphicsMill.Bitmap bitmap = new Aurigma.GraphicsMill.Bitmap(134, 135, Aurigma.GraphicsMill.PixelFormat.Format24bppRgb);
bitmap.Load(@"C:\Temp\test.png");
Aurigma.GraphicsMill.Drawing.GdiGraphics graphics = bitmap.GetGdiGraphics();
//Adjust font settings
Aurigma.GraphicsMill.Drawing.Font font = new Aurigma.GraphicsMill.Drawing.Font("Arial", 12, false, false);
font.VerticalAlignment = Aurigma.GraphicsMill.Drawing.VerticalAlignment.Bottom;
font.HorizontalAlignment = Aurigma.GraphicsMill.Drawing.HorizontalAlignment.Center;
string text = "Rounded sample text ";
//Get characters positions
float[] positions = font.GetCharacterPositions(text, 0);
//Get string width
float strWidth = font.MeasureString(text).Width;
//Get string height
float strHeight = font.MeasureString(text).Height;
Aurigma.GraphicsMill.Drawing.SolidBrush brush = new Aurigma.GraphicsMill.Drawing.SolidBrush(Aurigma.GraphicsMill.RgbColor.Black);
//Draw character by character
for (int i = 0; i < text.Length; i++)
{
float charWidth = font.GetBlackBox(text[i]).Width;
//Compute angle to which rotate current character. Rotation will be
//performed relative to the middle of the bottom side of the character.
float angle = (float)(2*Math.PI - (positions[i] + charWidth / 2.0f) * Math.PI / strWidth);
//Compute the x and y coordinate of the bottom/top* middle* of the character
float x = (float)(centerX + radius * Math.Cos(angle));
float y = (float)(centerY - radius * Math.Sin(angle));
System.Drawing.Drawing2D.Matrix rotateMatrix = new System.Drawing.Drawing2D.Matrix();
//Convert angle from radians to degrees
float degAngle = (float)(angle / Math.PI * 180);
rotateMatrix.RotateAt(90 - degAngle, new System.Drawing.PointF(x, y));
graphics.Transform = rotateMatrix;
graphics.DrawString(text[i].ToString(), font, brush, x, y);
}
bitmap.Save(@"C:\Temp\NewImage2.png");
If you have any additional questions please feel free to let me know. |
Best regards, Dmitry Obukhov
Technical Support. Aurigma, Inc.
|
|
|
|
Rank: Newbie
Groups: Member
Joined: 12/2/2010(UTC) Posts: 4
Thanks: 1 times
|
Hi Dmitry Can you please provide your thoughts on these 2 minor issues? We're about to finish our codebase and this is the only one left. Your quick response in this regard will be highly appreciated. Best regards, ---------------------------------------------------------------------------------------- Hi Dmitry, Many thanks for your quick response. I'm getting close to my solution. Couple of more queries: 1) I want the 2nd (bottom) line starting from left hand side middle part and not from right hand side middle part. If you look at first line, it starts from left side and goes up and then come down from left to right. I want 2nd line similar from left side, goes down and then up from left to right. Hope you understand. I'm sure there should be minor setting in radius or somewhere. 2) It looks like the more characters you've the less spacings in between the characters. However, if I have only few characters, let's say "Dmitry", it puts lot of space between each character. Is there anyway, we can fix the spacing between and add some spacings on left side of the text and right side of the text so the "text" always look horizontally centered aligned. Refer to attached two images for point #2. Regards and thanks you. Edited by user Tuesday, December 14, 2010 1:29:13 PM(UTC)
| Reason: Not specified SteveH attached the following image(s):
|
|
|
|
Rank: Advanced Member
Groups: Member
Joined: 1/31/2005(UTC) Posts: 458
Was thanked: 5 time(s) in 5 post(s)
|
Hello SteveH, I added few parameters to the Dmitry's code, so you can now easily adjust start angle of the text and range occupied by text. Here is rendering method: Code:public void Draw(string text, Aurigma.GraphicsMill.Bitmap bmp, int centerX, int centerY, int radius, double startAngle, double range, bool useAverageCharWidth)
{
using (GdiGraphics g = bmp.GetGdiGraphics())
{
Font font = new Font("Calibri", 32, false, false);
font.Antialiased = true;
font.VerticalAlignment = VerticalAlignment.Bottom;
font.HorizontalAlignment = HorizontalAlignment.Center;
System.Drawing.SizeF textSize = font.MeasureString(text);
float[] positions;
if (useAverageCharWidth)
{
textSize.Width = text.Length * font.AverageCharWidth;
positions = new float[text.Length];
for (int i = 0; i < positions.Length; i++)
positions[i] = i * font.AverageCharWidth;
}
else
{
positions = font.GetCharacterPositions(text, 0);
}
System.Drawing.Drawing2D.Matrix m = new System.Drawing.Drawing2D.Matrix();
SolidBrush brush = new SolidBrush(Aurigma.GraphicsMill.RgbColor.Black);
for (int i = 0; i < text.Length; i++)
{
float charWidth;
if (useAverageCharWidth)
charWidth = font.AverageCharWidth / 2;
else
charWidth = font.GetBlackBox(text[i]).Width;
//Compute angle to which rotate current character. Rotation will be
//performed relative to the middle of the bottom side of the character.
double angle = 2 * Math.PI - (positions[i] + charWidth / 2.0f) * range / textSize.Width;
angle -= startAngle;
//Convert angle from radians to degrees
float degAngle = (float)(angle / Math.PI * 180);
//Compute the x and y coordinate of the bottom/top* middle* of the character
float x = (float)(centerX + radius * Math.Cos(angle));
float y = (float)(centerY - radius * Math.Sin(angle));
m.Reset();
m.RotateAt(90 - degAngle, new System.Drawing.PointF(x, y));
g.Transform = m;
g.DrawString(text[i].ToString(), font, brush, x, y);
}
}
}
Please note, that startAngle and range should be specified in radians, not in degrees. The last parameter was added to obtain more uniform text placing with large ranges. Maybe you already noticed that when we have relatively short text with large range - some spacings between characters significantly larger than other. It occurs because small spacing differences in usual text are multiplied when we put it "on circle". The simplest way to fix it is to use just average character width. With large ranges this results in better-looking results. However for smaller ranges this approach may not be acceptable. Feel free to experiment with this method. I wrote tiny test app to play with settings, you can find it in attachments to the post. Edited by user Wednesday, December 15, 2010 3:30:18 AM(UTC)
| Reason: Not specified File Attachment(s): Alex Kon attached the following image(s): |
|
1 user thanked Alex Kon for this useful post.
|
|
|
Aurigma Forums
»
Graphics Mill
»
Discussions – Graphics Mill
»
Write Curved text on an existing image around the round edge
Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.