How can I render curved text into a Bitmap?











up vote
4
down vote

favorite
5












I am currently dynamically creating a bitmap and using the graphics object from the bitmap to draw a string on it like so:



System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.DrawString(text, font, brush, new System.Drawing.Point(0, 0));


This returns a rectangular bitmap with the string written straight across from left to right.
I would like to also be able to draw the string in the shape of a rainbow.
How can I do this?










share|improve this question




















  • 1




    Were any of these answers helpful? I just came across this question and might code something similar soon, but none of the answers have been accepted - I am wondering if there were problems with them, and what you ended up doing.
    – David M
    May 13 '13 at 11:48










  • Use this: csharphelper.com/blog/2016/01/draw-text-on-a-curve-in-c
    – M.R.T2017
    Aug 18 at 14:15















up vote
4
down vote

favorite
5












I am currently dynamically creating a bitmap and using the graphics object from the bitmap to draw a string on it like so:



System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.DrawString(text, font, brush, new System.Drawing.Point(0, 0));


This returns a rectangular bitmap with the string written straight across from left to right.
I would like to also be able to draw the string in the shape of a rainbow.
How can I do this?










share|improve this question




















  • 1




    Were any of these answers helpful? I just came across this question and might code something similar soon, but none of the answers have been accepted - I am wondering if there were problems with them, and what you ended up doing.
    – David M
    May 13 '13 at 11:48










  • Use this: csharphelper.com/blog/2016/01/draw-text-on-a-curve-in-c
    – M.R.T2017
    Aug 18 at 14:15













up vote
4
down vote

favorite
5









up vote
4
down vote

favorite
5






5





I am currently dynamically creating a bitmap and using the graphics object from the bitmap to draw a string on it like so:



System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.DrawString(text, font, brush, new System.Drawing.Point(0, 0));


This returns a rectangular bitmap with the string written straight across from left to right.
I would like to also be able to draw the string in the shape of a rainbow.
How can I do this?










share|improve this question















I am currently dynamically creating a bitmap and using the graphics object from the bitmap to draw a string on it like so:



System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.DrawString(text, font, brush, new System.Drawing.Point(0, 0));


This returns a rectangular bitmap with the string written straight across from left to right.
I would like to also be able to draw the string in the shape of a rainbow.
How can I do this?







c# bitmap gdi+ text-rendering






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Aug 28 '14 at 3:48









Simon MᶜKenzie

6,205133257




6,205133257










asked May 10 '10 at 15:22









etoisarobot

4,279114372




4,279114372








  • 1




    Were any of these answers helpful? I just came across this question and might code something similar soon, but none of the answers have been accepted - I am wondering if there were problems with them, and what you ended up doing.
    – David M
    May 13 '13 at 11:48










  • Use this: csharphelper.com/blog/2016/01/draw-text-on-a-curve-in-c
    – M.R.T2017
    Aug 18 at 14:15














  • 1




    Were any of these answers helpful? I just came across this question and might code something similar soon, but none of the answers have been accepted - I am wondering if there were problems with them, and what you ended up doing.
    – David M
    May 13 '13 at 11:48










  • Use this: csharphelper.com/blog/2016/01/draw-text-on-a-curve-in-c
    – M.R.T2017
    Aug 18 at 14:15








1




1




Were any of these answers helpful? I just came across this question and might code something similar soon, but none of the answers have been accepted - I am wondering if there were problems with them, and what you ended up doing.
– David M
May 13 '13 at 11:48




Were any of these answers helpful? I just came across this question and might code something similar soon, but none of the answers have been accepted - I am wondering if there were problems with them, and what you ended up doing.
– David M
May 13 '13 at 11:48












Use this: csharphelper.com/blog/2016/01/draw-text-on-a-curve-in-c
– M.R.T2017
Aug 18 at 14:15




Use this: csharphelper.com/blog/2016/01/draw-text-on-a-curve-in-c
– M.R.T2017
Aug 18 at 14:15












3 Answers
3






active

oldest

votes

















up vote
17
down vote













I recently had this problem (I was rendering text for printing onto CDs), so here's my solution:



private void DrawCurvedText(Graphics graphics, string text, Point centre, float distanceFromCentreToBaseOfText, float radiansToTextCentre, Font font, Brush brush)
{
// Circumference for use later
var circleCircumference = (float)(Math.PI * 2 * distanceFromCentreToBaseOfText);

// Get the width of each character
var characterWidths = GetCharacterWidths(graphics, text, font).ToArray();

// The overall height of the string
var characterHeight = graphics.MeasureString(text, font).Height;

var textLength = characterWidths.Sum();

// The string length above is the arc length we'll use for rendering the string. Work out the starting angle required to
// centre the text across the radiansToTextCentre.
float fractionOfCircumference = textLength / circleCircumference;

float currentCharacterRadians = radiansToTextCentre + (float)(Math.PI * fractionOfCircumference);

for (int characterIndex = 0; characterIndex < text.Length; characterIndex++)
{
char @char = text[characterIndex];

// Polar to cartesian
float x = (float)(distanceFromCentreToBaseOfText * Math.Sin(currentCharacterRadians));
float y = -(float)(distanceFromCentreToBaseOfText * Math.Cos(currentCharacterRadians));

using (GraphicsPath characterPath = new GraphicsPath())
{
characterPath.AddString(@char.ToString(), font.FontFamily, (int)font.Style, font.Size, Point.Empty,
StringFormat.GenericTypographic);

var pathBounds = characterPath.GetBounds();

// Transformation matrix to move the character to the correct location.
// Note that all actions on the Matrix class are prepended, so we apply them in reverse.
var transform = new Matrix();

// Translate to the final position
transform.Translate(centre.X + x, centre.Y + y);

// Rotate the character
var rotationAngleDegrees = currentCharacterRadians * 180F / (float)Math.PI - 180F;
transform.Rotate(rotationAngleDegrees);

// Translate the character so the centre of its base is over the origin
transform.Translate(-pathBounds.Width / 2F, -characterHeight);

characterPath.Transform(transform);

// Draw the character
graphics.FillPath(brush, characterPath);
}

if (characterIndex != text.Length - 1)
{
// Move "currentCharacterRadians" on to the next character
var distanceToNextChar = (characterWidths[characterIndex] + characterWidths[characterIndex + 1]) / 2F;
float charFractionOfCircumference = distanceToNextChar / circleCircumference;
currentCharacterRadians -= charFractionOfCircumference * (float)(2F * Math.PI);
}
}
}

private IEnumerable<float> GetCharacterWidths(Graphics graphics, string text, Font font)
{
// The length of a space. Necessary because a space measured using StringFormat.GenericTypographic has no width.
// We can't use StringFormat.GenericDefault for the characters themselves, as it adds unwanted spacing.
var spaceLength = graphics.MeasureString(" ", font, Point.Empty, StringFormat.GenericDefault).Width;

return text.Select(c => c == ' ' ? spaceLength : graphics.MeasureString(c.ToString(), font, Point.Empty, StringFormat.GenericTypographic).Width);
}


screenshot of curved text in program output






share|improve this answer

















  • 1




    Of all of the countless posts on the internet, this is the only example I've found of a fairly simple method of doing this. I was in the process of using bezier curves to achieve it. Thanks @Simon.
    – Echilon
    Sep 10 '13 at 16:06










  • One slight observation with this is that text goes anti-clockwise. Is it possible to make it go clockwise instead?
    – Echilon
    Sep 10 '13 at 16:15






  • 3




    Hi @Echilon, you can reverse the curve by changing a couple of lines: remove the -180F when calculating rotationAngleDegrees, and in the 2 places where currentCharacterRadians is assigned, change the subtractions to additions and vice versa!
    – Simon MᶜKenzie
    Sep 11 '13 at 4:45










  • Works great. Thanks.
    – Echilon
    Sep 11 '13 at 18:23






  • 1




    @Rasool, I'm afraid that's beyond my expertise! You should ask a new question about it, explaining the rtl problem. Good luck!
    – Simon MᶜKenzie
    Mar 20 '15 at 8:43


















up vote
1
down vote













I think the only way is to render each character individually and use the



Graphics.RotateTransform


to rotate the text. You'll need to work out the rotation angle and rendering offset yourself. You can use the



Graphics.MeasureCharacterRanges


to get the size of each character.






share|improve this answer





















  • I personally am going to love this solution! +1 :) Thanks for suggestion.
    – Afzaal Ahmad Zeeshan
    Aug 17 '14 at 12:27


















up vote
0
down vote













Unfortunatelly in GDI+ there is no way to attach Strings to a path (this is what you would be looking for).



So the only way to do this is doing it "by hand". That means splitting up the string into characters and placing them based on your own path calculations.



Unless you want to put a lot of work into this you should try to find a library (potentially complete GDI+ replacement) to do this or give up on your rainbow.



With WPF you can render text on a path (see link for a howto)






share|improve this answer























  • 8 years, and still working. Thanks for this
    – HEWhoDoesn'tKnow
    Nov 10 at 0:55











Your Answer






StackExchange.ifUsing("editor", function () {
StackExchange.using("externalEditor", function () {
StackExchange.using("snippets", function () {
StackExchange.snippets.init();
});
});
}, "code-snippets");

StackExchange.ready(function() {
var channelOptions = {
tags: "".split(" "),
id: "1"
};
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function() {
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled) {
StackExchange.using("snippets", function() {
createEditor();
});
}
else {
createEditor();
}
});

function createEditor() {
StackExchange.prepareEditor({
heartbeatType: 'answer',
convertImagesToLinks: true,
noModals: true,
showLowRepImageUploadWarning: true,
reputationToPostImages: 10,
bindNavPrevention: true,
postfix: "",
imageUploader: {
brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
allowUrls: true
},
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
});


}
});














draft saved

draft discarded


















StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2803853%2fhow-can-i-render-curved-text-into-a-bitmap%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown

























3 Answers
3






active

oldest

votes








3 Answers
3






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
17
down vote













I recently had this problem (I was rendering text for printing onto CDs), so here's my solution:



private void DrawCurvedText(Graphics graphics, string text, Point centre, float distanceFromCentreToBaseOfText, float radiansToTextCentre, Font font, Brush brush)
{
// Circumference for use later
var circleCircumference = (float)(Math.PI * 2 * distanceFromCentreToBaseOfText);

// Get the width of each character
var characterWidths = GetCharacterWidths(graphics, text, font).ToArray();

// The overall height of the string
var characterHeight = graphics.MeasureString(text, font).Height;

var textLength = characterWidths.Sum();

// The string length above is the arc length we'll use for rendering the string. Work out the starting angle required to
// centre the text across the radiansToTextCentre.
float fractionOfCircumference = textLength / circleCircumference;

float currentCharacterRadians = radiansToTextCentre + (float)(Math.PI * fractionOfCircumference);

for (int characterIndex = 0; characterIndex < text.Length; characterIndex++)
{
char @char = text[characterIndex];

// Polar to cartesian
float x = (float)(distanceFromCentreToBaseOfText * Math.Sin(currentCharacterRadians));
float y = -(float)(distanceFromCentreToBaseOfText * Math.Cos(currentCharacterRadians));

using (GraphicsPath characterPath = new GraphicsPath())
{
characterPath.AddString(@char.ToString(), font.FontFamily, (int)font.Style, font.Size, Point.Empty,
StringFormat.GenericTypographic);

var pathBounds = characterPath.GetBounds();

// Transformation matrix to move the character to the correct location.
// Note that all actions on the Matrix class are prepended, so we apply them in reverse.
var transform = new Matrix();

// Translate to the final position
transform.Translate(centre.X + x, centre.Y + y);

// Rotate the character
var rotationAngleDegrees = currentCharacterRadians * 180F / (float)Math.PI - 180F;
transform.Rotate(rotationAngleDegrees);

// Translate the character so the centre of its base is over the origin
transform.Translate(-pathBounds.Width / 2F, -characterHeight);

characterPath.Transform(transform);

// Draw the character
graphics.FillPath(brush, characterPath);
}

if (characterIndex != text.Length - 1)
{
// Move "currentCharacterRadians" on to the next character
var distanceToNextChar = (characterWidths[characterIndex] + characterWidths[characterIndex + 1]) / 2F;
float charFractionOfCircumference = distanceToNextChar / circleCircumference;
currentCharacterRadians -= charFractionOfCircumference * (float)(2F * Math.PI);
}
}
}

private IEnumerable<float> GetCharacterWidths(Graphics graphics, string text, Font font)
{
// The length of a space. Necessary because a space measured using StringFormat.GenericTypographic has no width.
// We can't use StringFormat.GenericDefault for the characters themselves, as it adds unwanted spacing.
var spaceLength = graphics.MeasureString(" ", font, Point.Empty, StringFormat.GenericDefault).Width;

return text.Select(c => c == ' ' ? spaceLength : graphics.MeasureString(c.ToString(), font, Point.Empty, StringFormat.GenericTypographic).Width);
}


screenshot of curved text in program output






share|improve this answer

















  • 1




    Of all of the countless posts on the internet, this is the only example I've found of a fairly simple method of doing this. I was in the process of using bezier curves to achieve it. Thanks @Simon.
    – Echilon
    Sep 10 '13 at 16:06










  • One slight observation with this is that text goes anti-clockwise. Is it possible to make it go clockwise instead?
    – Echilon
    Sep 10 '13 at 16:15






  • 3




    Hi @Echilon, you can reverse the curve by changing a couple of lines: remove the -180F when calculating rotationAngleDegrees, and in the 2 places where currentCharacterRadians is assigned, change the subtractions to additions and vice versa!
    – Simon MᶜKenzie
    Sep 11 '13 at 4:45










  • Works great. Thanks.
    – Echilon
    Sep 11 '13 at 18:23






  • 1




    @Rasool, I'm afraid that's beyond my expertise! You should ask a new question about it, explaining the rtl problem. Good luck!
    – Simon MᶜKenzie
    Mar 20 '15 at 8:43















up vote
17
down vote













I recently had this problem (I was rendering text for printing onto CDs), so here's my solution:



private void DrawCurvedText(Graphics graphics, string text, Point centre, float distanceFromCentreToBaseOfText, float radiansToTextCentre, Font font, Brush brush)
{
// Circumference for use later
var circleCircumference = (float)(Math.PI * 2 * distanceFromCentreToBaseOfText);

// Get the width of each character
var characterWidths = GetCharacterWidths(graphics, text, font).ToArray();

// The overall height of the string
var characterHeight = graphics.MeasureString(text, font).Height;

var textLength = characterWidths.Sum();

// The string length above is the arc length we'll use for rendering the string. Work out the starting angle required to
// centre the text across the radiansToTextCentre.
float fractionOfCircumference = textLength / circleCircumference;

float currentCharacterRadians = radiansToTextCentre + (float)(Math.PI * fractionOfCircumference);

for (int characterIndex = 0; characterIndex < text.Length; characterIndex++)
{
char @char = text[characterIndex];

// Polar to cartesian
float x = (float)(distanceFromCentreToBaseOfText * Math.Sin(currentCharacterRadians));
float y = -(float)(distanceFromCentreToBaseOfText * Math.Cos(currentCharacterRadians));

using (GraphicsPath characterPath = new GraphicsPath())
{
characterPath.AddString(@char.ToString(), font.FontFamily, (int)font.Style, font.Size, Point.Empty,
StringFormat.GenericTypographic);

var pathBounds = characterPath.GetBounds();

// Transformation matrix to move the character to the correct location.
// Note that all actions on the Matrix class are prepended, so we apply them in reverse.
var transform = new Matrix();

// Translate to the final position
transform.Translate(centre.X + x, centre.Y + y);

// Rotate the character
var rotationAngleDegrees = currentCharacterRadians * 180F / (float)Math.PI - 180F;
transform.Rotate(rotationAngleDegrees);

// Translate the character so the centre of its base is over the origin
transform.Translate(-pathBounds.Width / 2F, -characterHeight);

characterPath.Transform(transform);

// Draw the character
graphics.FillPath(brush, characterPath);
}

if (characterIndex != text.Length - 1)
{
// Move "currentCharacterRadians" on to the next character
var distanceToNextChar = (characterWidths[characterIndex] + characterWidths[characterIndex + 1]) / 2F;
float charFractionOfCircumference = distanceToNextChar / circleCircumference;
currentCharacterRadians -= charFractionOfCircumference * (float)(2F * Math.PI);
}
}
}

private IEnumerable<float> GetCharacterWidths(Graphics graphics, string text, Font font)
{
// The length of a space. Necessary because a space measured using StringFormat.GenericTypographic has no width.
// We can't use StringFormat.GenericDefault for the characters themselves, as it adds unwanted spacing.
var spaceLength = graphics.MeasureString(" ", font, Point.Empty, StringFormat.GenericDefault).Width;

return text.Select(c => c == ' ' ? spaceLength : graphics.MeasureString(c.ToString(), font, Point.Empty, StringFormat.GenericTypographic).Width);
}


screenshot of curved text in program output






share|improve this answer

















  • 1




    Of all of the countless posts on the internet, this is the only example I've found of a fairly simple method of doing this. I was in the process of using bezier curves to achieve it. Thanks @Simon.
    – Echilon
    Sep 10 '13 at 16:06










  • One slight observation with this is that text goes anti-clockwise. Is it possible to make it go clockwise instead?
    – Echilon
    Sep 10 '13 at 16:15






  • 3




    Hi @Echilon, you can reverse the curve by changing a couple of lines: remove the -180F when calculating rotationAngleDegrees, and in the 2 places where currentCharacterRadians is assigned, change the subtractions to additions and vice versa!
    – Simon MᶜKenzie
    Sep 11 '13 at 4:45










  • Works great. Thanks.
    – Echilon
    Sep 11 '13 at 18:23






  • 1




    @Rasool, I'm afraid that's beyond my expertise! You should ask a new question about it, explaining the rtl problem. Good luck!
    – Simon MᶜKenzie
    Mar 20 '15 at 8:43













up vote
17
down vote










up vote
17
down vote









I recently had this problem (I was rendering text for printing onto CDs), so here's my solution:



private void DrawCurvedText(Graphics graphics, string text, Point centre, float distanceFromCentreToBaseOfText, float radiansToTextCentre, Font font, Brush brush)
{
// Circumference for use later
var circleCircumference = (float)(Math.PI * 2 * distanceFromCentreToBaseOfText);

// Get the width of each character
var characterWidths = GetCharacterWidths(graphics, text, font).ToArray();

// The overall height of the string
var characterHeight = graphics.MeasureString(text, font).Height;

var textLength = characterWidths.Sum();

// The string length above is the arc length we'll use for rendering the string. Work out the starting angle required to
// centre the text across the radiansToTextCentre.
float fractionOfCircumference = textLength / circleCircumference;

float currentCharacterRadians = radiansToTextCentre + (float)(Math.PI * fractionOfCircumference);

for (int characterIndex = 0; characterIndex < text.Length; characterIndex++)
{
char @char = text[characterIndex];

// Polar to cartesian
float x = (float)(distanceFromCentreToBaseOfText * Math.Sin(currentCharacterRadians));
float y = -(float)(distanceFromCentreToBaseOfText * Math.Cos(currentCharacterRadians));

using (GraphicsPath characterPath = new GraphicsPath())
{
characterPath.AddString(@char.ToString(), font.FontFamily, (int)font.Style, font.Size, Point.Empty,
StringFormat.GenericTypographic);

var pathBounds = characterPath.GetBounds();

// Transformation matrix to move the character to the correct location.
// Note that all actions on the Matrix class are prepended, so we apply them in reverse.
var transform = new Matrix();

// Translate to the final position
transform.Translate(centre.X + x, centre.Y + y);

// Rotate the character
var rotationAngleDegrees = currentCharacterRadians * 180F / (float)Math.PI - 180F;
transform.Rotate(rotationAngleDegrees);

// Translate the character so the centre of its base is over the origin
transform.Translate(-pathBounds.Width / 2F, -characterHeight);

characterPath.Transform(transform);

// Draw the character
graphics.FillPath(brush, characterPath);
}

if (characterIndex != text.Length - 1)
{
// Move "currentCharacterRadians" on to the next character
var distanceToNextChar = (characterWidths[characterIndex] + characterWidths[characterIndex + 1]) / 2F;
float charFractionOfCircumference = distanceToNextChar / circleCircumference;
currentCharacterRadians -= charFractionOfCircumference * (float)(2F * Math.PI);
}
}
}

private IEnumerable<float> GetCharacterWidths(Graphics graphics, string text, Font font)
{
// The length of a space. Necessary because a space measured using StringFormat.GenericTypographic has no width.
// We can't use StringFormat.GenericDefault for the characters themselves, as it adds unwanted spacing.
var spaceLength = graphics.MeasureString(" ", font, Point.Empty, StringFormat.GenericDefault).Width;

return text.Select(c => c == ' ' ? spaceLength : graphics.MeasureString(c.ToString(), font, Point.Empty, StringFormat.GenericTypographic).Width);
}


screenshot of curved text in program output






share|improve this answer












I recently had this problem (I was rendering text for printing onto CDs), so here's my solution:



private void DrawCurvedText(Graphics graphics, string text, Point centre, float distanceFromCentreToBaseOfText, float radiansToTextCentre, Font font, Brush brush)
{
// Circumference for use later
var circleCircumference = (float)(Math.PI * 2 * distanceFromCentreToBaseOfText);

// Get the width of each character
var characterWidths = GetCharacterWidths(graphics, text, font).ToArray();

// The overall height of the string
var characterHeight = graphics.MeasureString(text, font).Height;

var textLength = characterWidths.Sum();

// The string length above is the arc length we'll use for rendering the string. Work out the starting angle required to
// centre the text across the radiansToTextCentre.
float fractionOfCircumference = textLength / circleCircumference;

float currentCharacterRadians = radiansToTextCentre + (float)(Math.PI * fractionOfCircumference);

for (int characterIndex = 0; characterIndex < text.Length; characterIndex++)
{
char @char = text[characterIndex];

// Polar to cartesian
float x = (float)(distanceFromCentreToBaseOfText * Math.Sin(currentCharacterRadians));
float y = -(float)(distanceFromCentreToBaseOfText * Math.Cos(currentCharacterRadians));

using (GraphicsPath characterPath = new GraphicsPath())
{
characterPath.AddString(@char.ToString(), font.FontFamily, (int)font.Style, font.Size, Point.Empty,
StringFormat.GenericTypographic);

var pathBounds = characterPath.GetBounds();

// Transformation matrix to move the character to the correct location.
// Note that all actions on the Matrix class are prepended, so we apply them in reverse.
var transform = new Matrix();

// Translate to the final position
transform.Translate(centre.X + x, centre.Y + y);

// Rotate the character
var rotationAngleDegrees = currentCharacterRadians * 180F / (float)Math.PI - 180F;
transform.Rotate(rotationAngleDegrees);

// Translate the character so the centre of its base is over the origin
transform.Translate(-pathBounds.Width / 2F, -characterHeight);

characterPath.Transform(transform);

// Draw the character
graphics.FillPath(brush, characterPath);
}

if (characterIndex != text.Length - 1)
{
// Move "currentCharacterRadians" on to the next character
var distanceToNextChar = (characterWidths[characterIndex] + characterWidths[characterIndex + 1]) / 2F;
float charFractionOfCircumference = distanceToNextChar / circleCircumference;
currentCharacterRadians -= charFractionOfCircumference * (float)(2F * Math.PI);
}
}
}

private IEnumerable<float> GetCharacterWidths(Graphics graphics, string text, Font font)
{
// The length of a space. Necessary because a space measured using StringFormat.GenericTypographic has no width.
// We can't use StringFormat.GenericDefault for the characters themselves, as it adds unwanted spacing.
var spaceLength = graphics.MeasureString(" ", font, Point.Empty, StringFormat.GenericDefault).Width;

return text.Select(c => c == ' ' ? spaceLength : graphics.MeasureString(c.ToString(), font, Point.Empty, StringFormat.GenericTypographic).Width);
}


screenshot of curved text in program output







share|improve this answer












share|improve this answer



share|improve this answer










answered Jun 22 '12 at 6:53









Simon MᶜKenzie

6,205133257




6,205133257








  • 1




    Of all of the countless posts on the internet, this is the only example I've found of a fairly simple method of doing this. I was in the process of using bezier curves to achieve it. Thanks @Simon.
    – Echilon
    Sep 10 '13 at 16:06










  • One slight observation with this is that text goes anti-clockwise. Is it possible to make it go clockwise instead?
    – Echilon
    Sep 10 '13 at 16:15






  • 3




    Hi @Echilon, you can reverse the curve by changing a couple of lines: remove the -180F when calculating rotationAngleDegrees, and in the 2 places where currentCharacterRadians is assigned, change the subtractions to additions and vice versa!
    – Simon MᶜKenzie
    Sep 11 '13 at 4:45










  • Works great. Thanks.
    – Echilon
    Sep 11 '13 at 18:23






  • 1




    @Rasool, I'm afraid that's beyond my expertise! You should ask a new question about it, explaining the rtl problem. Good luck!
    – Simon MᶜKenzie
    Mar 20 '15 at 8:43














  • 1




    Of all of the countless posts on the internet, this is the only example I've found of a fairly simple method of doing this. I was in the process of using bezier curves to achieve it. Thanks @Simon.
    – Echilon
    Sep 10 '13 at 16:06










  • One slight observation with this is that text goes anti-clockwise. Is it possible to make it go clockwise instead?
    – Echilon
    Sep 10 '13 at 16:15






  • 3




    Hi @Echilon, you can reverse the curve by changing a couple of lines: remove the -180F when calculating rotationAngleDegrees, and in the 2 places where currentCharacterRadians is assigned, change the subtractions to additions and vice versa!
    – Simon MᶜKenzie
    Sep 11 '13 at 4:45










  • Works great. Thanks.
    – Echilon
    Sep 11 '13 at 18:23






  • 1




    @Rasool, I'm afraid that's beyond my expertise! You should ask a new question about it, explaining the rtl problem. Good luck!
    – Simon MᶜKenzie
    Mar 20 '15 at 8:43








1




1




Of all of the countless posts on the internet, this is the only example I've found of a fairly simple method of doing this. I was in the process of using bezier curves to achieve it. Thanks @Simon.
– Echilon
Sep 10 '13 at 16:06




Of all of the countless posts on the internet, this is the only example I've found of a fairly simple method of doing this. I was in the process of using bezier curves to achieve it. Thanks @Simon.
– Echilon
Sep 10 '13 at 16:06












One slight observation with this is that text goes anti-clockwise. Is it possible to make it go clockwise instead?
– Echilon
Sep 10 '13 at 16:15




One slight observation with this is that text goes anti-clockwise. Is it possible to make it go clockwise instead?
– Echilon
Sep 10 '13 at 16:15




3




3




Hi @Echilon, you can reverse the curve by changing a couple of lines: remove the -180F when calculating rotationAngleDegrees, and in the 2 places where currentCharacterRadians is assigned, change the subtractions to additions and vice versa!
– Simon MᶜKenzie
Sep 11 '13 at 4:45




Hi @Echilon, you can reverse the curve by changing a couple of lines: remove the -180F when calculating rotationAngleDegrees, and in the 2 places where currentCharacterRadians is assigned, change the subtractions to additions and vice versa!
– Simon MᶜKenzie
Sep 11 '13 at 4:45












Works great. Thanks.
– Echilon
Sep 11 '13 at 18:23




Works great. Thanks.
– Echilon
Sep 11 '13 at 18:23




1




1




@Rasool, I'm afraid that's beyond my expertise! You should ask a new question about it, explaining the rtl problem. Good luck!
– Simon MᶜKenzie
Mar 20 '15 at 8:43




@Rasool, I'm afraid that's beyond my expertise! You should ask a new question about it, explaining the rtl problem. Good luck!
– Simon MᶜKenzie
Mar 20 '15 at 8:43












up vote
1
down vote













I think the only way is to render each character individually and use the



Graphics.RotateTransform


to rotate the text. You'll need to work out the rotation angle and rendering offset yourself. You can use the



Graphics.MeasureCharacterRanges


to get the size of each character.






share|improve this answer





















  • I personally am going to love this solution! +1 :) Thanks for suggestion.
    – Afzaal Ahmad Zeeshan
    Aug 17 '14 at 12:27















up vote
1
down vote













I think the only way is to render each character individually and use the



Graphics.RotateTransform


to rotate the text. You'll need to work out the rotation angle and rendering offset yourself. You can use the



Graphics.MeasureCharacterRanges


to get the size of each character.






share|improve this answer





















  • I personally am going to love this solution! +1 :) Thanks for suggestion.
    – Afzaal Ahmad Zeeshan
    Aug 17 '14 at 12:27













up vote
1
down vote










up vote
1
down vote









I think the only way is to render each character individually and use the



Graphics.RotateTransform


to rotate the text. You'll need to work out the rotation angle and rendering offset yourself. You can use the



Graphics.MeasureCharacterRanges


to get the size of each character.






share|improve this answer












I think the only way is to render each character individually and use the



Graphics.RotateTransform


to rotate the text. You'll need to work out the rotation angle and rendering offset yourself. You can use the



Graphics.MeasureCharacterRanges


to get the size of each character.







share|improve this answer












share|improve this answer



share|improve this answer










answered May 10 '10 at 15:26









Skizz

43.5k859101




43.5k859101












  • I personally am going to love this solution! +1 :) Thanks for suggestion.
    – Afzaal Ahmad Zeeshan
    Aug 17 '14 at 12:27


















  • I personally am going to love this solution! +1 :) Thanks for suggestion.
    – Afzaal Ahmad Zeeshan
    Aug 17 '14 at 12:27
















I personally am going to love this solution! +1 :) Thanks for suggestion.
– Afzaal Ahmad Zeeshan
Aug 17 '14 at 12:27




I personally am going to love this solution! +1 :) Thanks for suggestion.
– Afzaal Ahmad Zeeshan
Aug 17 '14 at 12:27










up vote
0
down vote













Unfortunatelly in GDI+ there is no way to attach Strings to a path (this is what you would be looking for).



So the only way to do this is doing it "by hand". That means splitting up the string into characters and placing them based on your own path calculations.



Unless you want to put a lot of work into this you should try to find a library (potentially complete GDI+ replacement) to do this or give up on your rainbow.



With WPF you can render text on a path (see link for a howto)






share|improve this answer























  • 8 years, and still working. Thanks for this
    – HEWhoDoesn'tKnow
    Nov 10 at 0:55















up vote
0
down vote













Unfortunatelly in GDI+ there is no way to attach Strings to a path (this is what you would be looking for).



So the only way to do this is doing it "by hand". That means splitting up the string into characters and placing them based on your own path calculations.



Unless you want to put a lot of work into this you should try to find a library (potentially complete GDI+ replacement) to do this or give up on your rainbow.



With WPF you can render text on a path (see link for a howto)






share|improve this answer























  • 8 years, and still working. Thanks for this
    – HEWhoDoesn'tKnow
    Nov 10 at 0:55













up vote
0
down vote










up vote
0
down vote









Unfortunatelly in GDI+ there is no way to attach Strings to a path (this is what you would be looking for).



So the only way to do this is doing it "by hand". That means splitting up the string into characters and placing them based on your own path calculations.



Unless you want to put a lot of work into this you should try to find a library (potentially complete GDI+ replacement) to do this or give up on your rainbow.



With WPF you can render text on a path (see link for a howto)






share|improve this answer














Unfortunatelly in GDI+ there is no way to attach Strings to a path (this is what you would be looking for).



So the only way to do this is doing it "by hand". That means splitting up the string into characters and placing them based on your own path calculations.



Unless you want to put a lot of work into this you should try to find a library (potentially complete GDI+ replacement) to do this or give up on your rainbow.



With WPF you can render text on a path (see link for a howto)







share|improve this answer














share|improve this answer



share|improve this answer








edited May 10 '10 at 15:32

























answered May 10 '10 at 15:26









Foxfire

5,2211628




5,2211628












  • 8 years, and still working. Thanks for this
    – HEWhoDoesn'tKnow
    Nov 10 at 0:55


















  • 8 years, and still working. Thanks for this
    – HEWhoDoesn'tKnow
    Nov 10 at 0:55
















8 years, and still working. Thanks for this
– HEWhoDoesn'tKnow
Nov 10 at 0:55




8 years, and still working. Thanks for this
– HEWhoDoesn'tKnow
Nov 10 at 0:55


















draft saved

draft discarded




















































Thanks for contributing an answer to Stack Overflow!


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.





Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


Please pay close attention to the following guidance:


  • Please be sure to answer the question. Provide details and share your research!

But avoid



  • Asking for help, clarification, or responding to other answers.

  • Making statements based on opinion; back them up with references or personal experience.


To learn more, see our tips on writing great answers.




draft saved


draft discarded














StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f2803853%2fhow-can-i-render-curved-text-into-a-bitmap%23new-answer', 'question_page');
}
);

Post as a guest















Required, but never shown





















































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown

































Required, but never shown














Required, but never shown












Required, but never shown







Required, but never shown







Popular posts from this blog

Schultheiß

Android Play Services Check

Liste der Kulturdenkmale in Wilsdruff