SixLabors / ImageSharp.Drawing

:pen: Extensions to ImageSharp containing a cross-platform 2D polygon manipulation API and drawing operations.
https://sixlabors.com/products/imagesharp-drawing/
Other
284 stars 38 forks source link

DrawText over a BMP 128x64 displays deformed text #134

Open josellm opened 3 years ago

josellm commented 3 years ago

Description

I need to send a text to a 128x64 LCD display. I need to generate a bmp and draw some text over. I first use System.Drawing but due to problems with windows nano container I migrate the code to SixLabors.ImageSharp.

The resulting text with SixLabors.ImageSharp don't display smoothly like System.Drawing

Removing HorizontalAlignment and VerticalAlignment helps but it still doesn't show it correctly.

At left the version using System.Drawing, at the right using SixLabors.ImageSharp

2021-05-12 15-06-36

Steps to Reproduce

using (var img = new Image<Rgb24>(128, 64, Color.White)) {
    img.Mutate(x => x.DrawText(new TextGraphicsOptions() {
        TextOptions = new TextOptions() {
            HorizontalAlignment = HorizontalAlignment.Center,
            VerticalAlignment = VerticalAlignment.Center,
            WrapTextWidth = img.Width,
            ApplyKerning = true,
            DpiX = 100,
            DpiY = 100,
        },
        GraphicsOptions = new GraphicsOptions {
            Antialias = false,
            ColorBlendingMode = PixelColorBlendingMode.Normal
        }
    }, "Lorem ipsum dolor sit amet", SystemFonts.CreateFont("Tahoma", 8, FontStyle.Regular), Color.Black, new Point(0, 31)));
    img.SaveAsPng(filepath);
}

System Configuration

JimBobSquarePants commented 3 years ago

Do you have your description correct? The left image is much smoother than the right to me?

josellm commented 3 years ago

Yes sorry, I updated the description

JimBobSquarePants commented 3 years ago

Thanks, I’ll have a look!

tocsoft commented 3 years ago

This will likely be due to the fact we don't have support for font hinting... which when implemented will potentially require an (at least partially) reimplementation of our current text rasterizer. We currently try and render each glyph as few a times as possible and the hinting might cause us to offset oddly when trying to reuse an earlier raster at a new location (but we might get lucky and it turns out fine).

JimBobSquarePants commented 3 years ago

I just did a quick test and antialiasing seems to correct most issues. @tocsoft would that be expected for a lack of font hinting?

Antialias = false 134 - Copy

Antialias = true 134

It looks like something is broken with horizontal alignment with either our latest Fonts builds though. This is HorizontalAlignment.Center 134-hc

tocsoft commented 3 years ago

yeah, anti-aliasing hides a lot of sins.

josellm commented 3 years ago

Hi,

I take photos to the final result, first using System.Drawing, second using SixLabors without antialiasing and third with antialiasing. Antialiasing with LCD display is not a good choice.

IMG_20210513_115435 IMG_20210513_120427 IMG_20210513_121007

JimBobSquarePants commented 3 years ago

Thanks, yep. I was just confirming the expected behavior. We wouldn't suggest antialiasing as a workaround for LCD.

The only current workaround I would suggest would be to use a different font. We have an issue https://github.com/SixLabors/Fonts/issues/30 that tracks hinting but will need assistance implementing it.

antonfirsov commented 3 years ago

This is a reasonable request, but we won't be able to make it into 1.0 (see https://github.com/SixLabors/ImageSharp.Drawing/issues/134#issuecomment-839965138).

JimBobSquarePants commented 2 years ago

Hi @josellm I've just pushed an update into the MyGet feed 1.0.0-beta13.15 which adds a new property to TextOptions called ApplyHinting. It defaults to false currently as we still need to implement font specific adjustments to the hinting process but the basics should be there.

It would be really awesome if you could give that a spin for us and let us know if there are improvements to the output when enable. Thanks!

josellm commented 1 year ago

Hi @JimBobSquarePants , I'm sorry for being late but we finally stand with System.Drawing using "EnableUnixSupport". With .net7 System.Drawing on linux is not supported anymore and we return to the topic. Currently this is my system configuration:

ImageSharp.Drawing version:
SixLabors.ImageSharp Version=2.1.3
SixLabors.Fonts Version=1.0.0-beta18
SixLabors.ImageSharp.Drawing Version=1.0.0.beta15

Environment: Windows 11 & Docker Linux container

.NET Framework version: .Net 7.0

And with the current code:

        public void Test(string filepath) {
            var l8 = new L8();
            l8.FromRgb24(Color.White);
            using (var img = new Image<L8>(128, 64, l8)) {
                img.Mutate(x => x.DrawText(
                    new DrawingOptions() {
                        GraphicsOptions = new GraphicsOptions {
                            Antialias = false,
                        }
                    },
                    new TextOptions(SystemFonts.CreateFont("Tahoma", 8, FontStyle.Regular)) {
                        HorizontalAlignment = HorizontalAlignment.Left,
                        VerticalAlignment = VerticalAlignment.Top,
                        WrappingLength = _image.Width - 2,
                        TextAlignment = TextAlignment.Center,
                        KerningMode = KerningMode.None,
                        ColorFontSupport = ColorFontSupport.None,
                        Dpi = 100,
                        HintingMode = HintingMode.None,
                        Origin = new Point(0, 20)
                    }, "Lorem ipsum dolor sit amet", Brushes.Solid(Color.Black), null));
                img.SaveAsPng(filepath);
            }
        }

The result is: test

Changing HintingMode with HintXY the result is:

test

The first line seems to display better than the second line.

JimBobSquarePants commented 1 year ago

@josellm Can you try 1.0.0-beta19? I did a lot of work on font hinting in https://github.com/SixLabors/Fonts/pull/295 to improve output. You'll also want Antialias = true

JimBobSquarePants commented 1 year ago

Here's where we currently stand on this.

I'm not sure what else can be done here, I've exhausted everything I can think of on the font layout and hinting side (we don't do horizontal hinting as to get it to work with several older fonts you have to add a million hacks). Any additional changes would have to take place in the renderer/rasterizer itself I think which I don't recommend messing with.

image