System.Drawing.Font - 更改字母间距?

发布于 2024-12-11 03:27:41 字数 143 浏览 0 评论 0 原文

使用 System.Drawing.Font,有没有办法改变字母间距,就像改变字体大小一样?

我正在寻找增加字母间距以适应特定宽度。

如果这不可能,是否有其他方法可以达到预期的效果?例如,是否有一种简单的方法可以让多个图形适合我的特定宽度?

Using System.Drawing.Font, is there a way to change the Letter Spacing, just like you can change the Font Size?

I'm looking to increase the letter spacing to fit a specific width.

If this is not possible, are there alternatives to get the desired effect? For example, is there an easy way of having multiple graphics which will fit my specific width?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

大姐,你呐 2024-12-18 03:27:41

我认为 DrawString 不会允许您指定任何像字符之间的间距这样详细的内容,但我会创建一个辅助函数,根据所需的宽度计算间距,然后绘制每个字符以适应。

尝试一下,看看效果如何...

    public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth)
    {
        //Calculate spacing
        float widthNeeded = 0;
        foreach (char c in text)
        {
            widthNeeded += g.MeasureString(c.ToString(), font).Width;
        }
        float spacing = (desiredWidth - widthNeeded) / (text.Length - 1);

        //draw text
        float indent = 0;
        foreach (char c in text)
        {
            g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y));
            indent += g.MeasureString(c.ToString(), font).Width + spacing;
        }
    }

您可能可以对此进行优化,以便每个字符只调用一次 MeasureString。或者甚至使用 MeasureCharacterRanges 来获取一个数组(我相信无论如何它更准确)

编辑:这是一个使用 MeasureCharacterRanges 的示例......

    public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth)
    {
        //Calculate spacing
        float widthNeeded = 0;
        Region[] regions = g.MeasureCharacterRanges(text, font, new RectangleF(point, new SizeF(desiredWidth, font.Height + 10)), StringFormat.GenericDefault);
        float[] widths = new float[regions.Length];
        for(int i = 0; i < widths.Length; i++)
        {
            widths[i] = regions[i].GetBounds(g).Width;
            widthNeeded += widths[i];
        }
        float spacing = (desiredWidth - widthNeeded) / (text.Length - 1);

        //draw text
        float indent = 0;
        int index = 0;
        foreach (char c in text)
        {
            g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y));
            indent += widths[index] + spacing;
            index++;
        }
    }

I don't think DrawString will allow you to specify anything as detailed as the spacing between characters, but I would create a helper function that calculates spacing based on a desired width and then draw each character to fit.

Try this and see how you get on...

    public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth)
    {
        //Calculate spacing
        float widthNeeded = 0;
        foreach (char c in text)
        {
            widthNeeded += g.MeasureString(c.ToString(), font).Width;
        }
        float spacing = (desiredWidth - widthNeeded) / (text.Length - 1);

        //draw text
        float indent = 0;
        foreach (char c in text)
        {
            g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y));
            indent += g.MeasureString(c.ToString(), font).Width + spacing;
        }
    }

You could probably optimise this to make only one call to MeasureString per character. Or even use MeasureCharacterRanges to get an array (which I believe is more accurate anyway)

Edit: Here is an example using MeasureCharacterRanges instead...

    public void DrawSpacedText(Graphics g, Font font, Brush brush, PointF point, string text, int desiredWidth)
    {
        //Calculate spacing
        float widthNeeded = 0;
        Region[] regions = g.MeasureCharacterRanges(text, font, new RectangleF(point, new SizeF(desiredWidth, font.Height + 10)), StringFormat.GenericDefault);
        float[] widths = new float[regions.Length];
        for(int i = 0; i < widths.Length; i++)
        {
            widths[i] = regions[i].GetBounds(g).Width;
            widthNeeded += widths[i];
        }
        float spacing = (desiredWidth - widthNeeded) / (text.Length - 1);

        //draw text
        float indent = 0;
        int index = 0;
        foreach (char c in text)
        {
            g.DrawString(c.ToString(), font, brush, new PointF(point.X + indent, point.Y));
            indent += widths[index] + spacing;
            index++;
        }
    }
无边思念无边月 2024-12-18 03:27:41

此代码支持文本中的换行并返回 Image 对象。

public static Image ConvertTextToImage(String text, Font font, Color textColor, int spacing = 0)
{
    var textParts = SplitOnBreakLines(text);
    // dummy image, just create drawing
    var img = new Bitmap(1, 1);
    var drawing = Graphics.FromImage(img);
    // calculate width, height
    var width = 0.0F;
    foreach (char c in text)
    {
        width += drawing.MeasureString(c.ToString(), font).Width;
    }           
    width = (width + spacing * (ClearBreakLines(text).Length - 1))  / textParts.Length;
    if (width <= 0)
        width = 1;
    var height = font.Height * textParts.Length;
    // clear and create new objects
    img.Dispose();
    drawing.Dispose();

    img = new Bitmap((int)width, (int)height);
    drawing = Graphics.FromImage(img);

    //Adjust for high quality
    drawing.CompositingQuality = CompositingQuality.HighQuality;
    drawing.InterpolationMode = InterpolationMode.HighQualityBilinear;
    drawing.PixelOffsetMode = PixelOffsetMode.HighQuality;
    drawing.SmoothingMode = SmoothingMode.HighQuality;
    drawing.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

    //paint the background
    drawing.Clear(Color.Transparent);

    //create a brush for the text
    var textBrush = new SolidBrush(textColor);
    //write text
    var indent = 0.0F;
    var point = new Point();            
    foreach (var textPart in textParts)
    {
        foreach (char c in textPart)
        {
            drawing.DrawString(c.ToString(), font, textBrush, new PointF(point.X + indent, point.Y));
            indent += drawing.MeasureString(c.ToString(), font).Width + spacing;
        }
        indent = 0.0F;
        point.Y += font.Height;
    }
    drawing.Save();
    textBrush.Dispose();
    drawing.Dispose();
    return img;           
}

public static string ClearBreakLines(string s)
{
    return Regex.Replace(s, @"\r\n?|\n", string.Empty);
}

public static string[] SplitOnBreakLines(string s)
{
    return Regex.Split(s, @"\r\n?|\n");           
}

This code supports a new line in the text and returns an Image object.

public static Image ConvertTextToImage(String text, Font font, Color textColor, int spacing = 0)
{
    var textParts = SplitOnBreakLines(text);
    // dummy image, just create drawing
    var img = new Bitmap(1, 1);
    var drawing = Graphics.FromImage(img);
    // calculate width, height
    var width = 0.0F;
    foreach (char c in text)
    {
        width += drawing.MeasureString(c.ToString(), font).Width;
    }           
    width = (width + spacing * (ClearBreakLines(text).Length - 1))  / textParts.Length;
    if (width <= 0)
        width = 1;
    var height = font.Height * textParts.Length;
    // clear and create new objects
    img.Dispose();
    drawing.Dispose();

    img = new Bitmap((int)width, (int)height);
    drawing = Graphics.FromImage(img);

    //Adjust for high quality
    drawing.CompositingQuality = CompositingQuality.HighQuality;
    drawing.InterpolationMode = InterpolationMode.HighQualityBilinear;
    drawing.PixelOffsetMode = PixelOffsetMode.HighQuality;
    drawing.SmoothingMode = SmoothingMode.HighQuality;
    drawing.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;

    //paint the background
    drawing.Clear(Color.Transparent);

    //create a brush for the text
    var textBrush = new SolidBrush(textColor);
    //write text
    var indent = 0.0F;
    var point = new Point();            
    foreach (var textPart in textParts)
    {
        foreach (char c in textPart)
        {
            drawing.DrawString(c.ToString(), font, textBrush, new PointF(point.X + indent, point.Y));
            indent += drawing.MeasureString(c.ToString(), font).Width + spacing;
        }
        indent = 0.0F;
        point.Y += font.Height;
    }
    drawing.Save();
    textBrush.Dispose();
    drawing.Dispose();
    return img;           
}

public static string ClearBreakLines(string s)
{
    return Regex.Replace(s, @"\r\n?|\n", string.Empty);
}

public static string[] SplitOnBreakLines(string s)
{
    return Regex.Split(s, @"\r\n?|\n");           
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文