2

I'm trying to create an image by drawing a text using a TTF font. I'm using .net core 2.1.500 on MacOS, and have mono-libgdiplus v5.6 (installed via brew).

The TTF file is Neo Sans Medium and this is my code (I tried with different TTF fonts, always with the same result)

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);
}

Since it printed textFont: Neo Sans, it seems to me that it was properly loaded (otherwise, it would have defaulted to Verdana).

However, the output I'm getting is this one:

enter image description here

Am I missing something?

0

3 Answers 3

3

I was able to do it using SixLabors.ImageSharp. I also installed SixLabors.Fonts and SixLabors.ImageSharp.Drawing.

With this code:

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");
}

I was able to get this:

enter image description here

Sign up to request clarification or add additional context in comments.

1 Comment

Saved me after three days of attempts. The code in the question works like a charm in any other context (e.g. winforms, wpf, ...) but for a weird reason (that I can't find) it doesn't work in web api (.net core 5)
0

Hereby example of how to draw with a custom TTF font. No need to install the private font on this system.

The trick is loading the font in a PrivateFontCollection, then create a new Font using the loaded FontFamily of the collection.

In this example I used a barcode 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;
    }

Comments

0

I was able to get this working without switching to a different drawing library. Copy the FFT file to /usr/share/fonts/ and then switch to using a standard font instead of using PrivateFontCollection.

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

Installing the font may seem like a "hack" but if you are deploying your app in a container it's as simple as copying the TTF in your Dockerfile.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.