我目前動態創建位圖和使用圖形從位圖對象繪製一個字符串就可以了,像這樣:如何將曲線文本渲染到位圖中?
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.DrawString(text, font, brush, new System.Drawing.Point(0, 0));
此方法返回跨連續寫入字符串矩形位圖從左至右。 我想也能夠以彩虹的形狀繪製字符串。 我該怎麼做?
我目前動態創建位圖和使用圖形從位圖對象繪製一個字符串就可以了,像這樣:如何將曲線文本渲染到位圖中?
System.Drawing.Graphics graph = System.Drawing.Graphics.FromImage(bmp);
graph.DrawString(text, font, brush, new System.Drawing.Point(0, 0));
此方法返回跨連續寫入字符串矩形位圖從左至右。 我想也能夠以彩虹的形狀繪製字符串。 我該怎麼做?
我認爲,唯一的辦法就是單獨呈現每個字符,並使用
Graphics.RotateTransform
旋轉文本。你需要自己計算旋轉角度和渲染偏移量。您可以使用
Graphics.MeasureCharacterRanges
來獲取每個字符的大小。
我個人很喜歡這個解決方案! +1 :)感謝您的建議。 – 2014-08-17 12:27:25
不幸的是,在GDI +中,沒有辦法將字符串附加到路徑上(這是您要查找的內容)。
所以唯一的方法就是「手工」。這意味着將字符串分解爲字符並根據自己的路徑計算放置它們。
除非你想把lot的工作放到這裏,你應該嘗試找到一個庫(可能是完整的GDI +替代品)來做到這一點或放棄你的彩虹。
使用WPF,你可以在路徑上呈現文本(see link for a howto)
最近,我有這個問題(我是呈現文本打印到光盤),所以這裏是我的解決方案:
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);
}
這些答案有幫助嗎?我剛剛遇到了這個問題,可能很快就會編寫類似的代碼,但沒有一個答案被接受 - 我想知道他們是否存在問題,以及您最終做了什麼。 – 2013-05-13 11:48:54