【问题标题】:Can't use font from ttf file on DrawString无法在 DrawString 上使用 ttf 文件中的字体
【发布时间】:2019-01-06 20:06:15
【问题描述】:

我正在尝试通过使用 TTF 字体绘制文本来创建图像。我在 MacOS 上使用 .net core 2.1.500,并且拥有 mono-libgdiplus v5.6(通过 brew 安装)。

TTF 文件是 Neo Sans Medium,这是我的代码(我尝试了不同的 TTF 字体,结果总是相同)

using (var bmp = new Bitmap(1024, 512))
{
    Graphics g = Graphics.FromImage(bmp);
    g.Clear(Color.White);

    var rectf = new RectangleF(0, 40, 1024, 90);

    // If I specify a font that it doesn't know, it defaults to Verdana
    var defaultFont = new Font("DefaultFont", 55);
    Console.WriteLine($"defaultFont: {defaultFont.Name}"); // => defaultFont: Verdana

    g.DrawString("Text with default", defaultFont, Brushes.Black, rectf);

    var privateFontCollection = new PrivateFontCollection();
    privateFontCollection.AddFontFile("/path/to/Neo_Sans_Medium.ttf");
    var fontFamilies = privateFontCollection.Families;

    var family = fontFamilies[0];

    var familyHasRegular = family.IsStyleAvailable(FontStyle.Regular);
    Console.WriteLine($"familyHasRegular: {familyHasRegular}"); // => familyHasRegular: true

    var textFont = new Font(family, 55);
    Console.WriteLine($"textFont: {textFont.Name}"); // => textFont: Neo Sans

    var rectText = new RectangleF(0, 140, 1024 - 50 - 50, 1024 - 50 - 10);
    g.DrawString("Text with loaded font", textFont, Brushes.Black, rectText);

    g.Flush();

    g.Save();

    bmp.Save("test.png", ImageFormat.Png);
}

由于它打印了textFont: Neo Sans,在我看来它已正确加载(否则,它会默认为Verdana)。

但是,我得到的输出是这个:

我错过了什么吗?

【问题讨论】:

    标签: c# fonts .net-core drawing


    【解决方案1】:

    我可以使用SixLabors.ImageSharp 做到这一点。我还安装了SixLabors.FontsSixLabors.ImageSharp.Drawing

    使用此代码:

    using (Image<Rgba32> image = new Image<Rgba32>(1024, 512))
    {
        FontCollection fonts = new FontCollection();
        fonts.Install("/path/to/Neo_Sans_Medium.ttf");
    
        var verdana = SystemFonts.CreateFont("Verdana", 55);
        var neoSans = fonts.CreateFont("Neo Sans", 55);
    
        image.Mutate(x => x
            .BackgroundColor(Rgba32.White)
            .DrawText("Text with default", verdana, Rgba32.Black, new PointF(0, 0))
            .DrawText("Text with loaded font", neoSans, Rgba32.Black, new PointF(0, 65))
        );
        image.Save("out.png");
    }
    

    我得到了这个:

    【讨论】:

    • 经过三天的尝试救了我。问题中的代码在任何其他上下文(例如winforms,wpf,...)中都像一个魅力,但由于一个奇怪的原因(我找不到)它在web api(.net core 5)中不起作用
    【解决方案2】:

    在此示例如何使用自定义 TTF 字体进行绘制。本系统无需安装私有字体。

    诀窍是在 PrivateFontCollection 中加载字体, 然后使用加载的集合的 FontFamily 创建一个新的 Font。

    在本例中,我使用了条形码字体 KixBarcode。

        static Bitmap CreateBarcode(string text)
        {
            var collection = new PrivateFontCollection();
            collection.AddFontFile(@"F:\Projects\Tools\Rtf2Pdf\KixBarcode.ttf");
            var image = new Bitmap(300, 300);
            var g = Graphics.FromImage(image);
            var brush = new SolidBrush(Color.Black);
            var font = new Font(collection.Families[0], 12);
            g.Dispose();
    
            return image;
        }
    

    【讨论】:

      【解决方案3】:

      我能够在不切换到其他绘图库的情况下完成这项工作。将 FFT 文件复制到/usr/share/fonts/,然后切换到使用标准字体而不是使用 PrivateFontCollection。

      var font = new Font("Your Font Name", 50);
      g.DrawString("Hello world", font, Brushes.Black, rectf);
      

      安装字体可能看起来像“hack”,但如果您在容器中部署应用程序,就像在 Dockerfile 中复制 TTF 一样简单。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-10-06
        • 2021-08-12
        • 1970-01-01
        • 2022-08-19
        • 1970-01-01
        • 1970-01-01
        • 2015-12-23
        相关资源
        最近更新 更多