Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Drawing non-antialiased 1px high line at Y 0 coordinate is not rendered (coordinates seem to be off by 1) #28

Closed
3 of 4 tasks
atruskie opened this issue Feb 24, 2020 · 3 comments · Fixed by #70
Closed
3 of 4 tasks
Labels
bug Something isn't working

Comments

@atruskie
Copy link
Contributor

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

I'm trying to draw some non-antialiased 1px lines.

Steps to Reproduce

        static void Main(string[] args)
        {
            var image = new Image<Rgb24>(Configuration.Default, 100, 100, Color.Black);
            image.Mutate(x => x.DrawLines(
                new ShapeGraphicsOptions() { Antialias = false },
                Color.Red,
                1f,
                new PointF(0, 0),
                new PointF(100, 0)
                ));

            image.Save("test.png");
        }

Actual output:
test

Expected:
testExpected

System Configuration

  • ImageSharp.Drawing version: SixLabors.ImageSharp.Drawing 1.0.0-unstable0421
  • Other ImageSharp packages and versions: SixLabors.ImageSharp 1.0.0-unstable0702
  • Environment (Operating system, version and so on): Win 10, 19564.1000
  • .NET Framework version: .NET Core 3.1.200-preview-014977
  • Additional information:

For comparison, output from other cases follows:

Using y-offset of 1

test1

System.Drawing with y-offset of 0

            Bitmap b = new Bitmap(100, 100);
            var graphics = Graphics.FromImage(b);
            graphics.Clear(Color.Black);
            graphics.DrawLines(new Pen(Color.Red, 1), new[]
            {
                new PointF(0, 0),
                new PointF(100, 0)
            });


            b.Save("test_SD.bmp");

test_SD

SkiaSharp with y-offset of 0


            var image = new SKBitmap(new SKImageInfo(100, 100, SKColorType.Rgba8888));
            var canvas = new SKCanvas(image);
            canvas.Clear(SKColors.Black);

            SKPaint thinLinePaint = new SKPaint
            {
                Style = SKPaintStyle.Stroke,
                Color = SKColors.Red,
                StrokeWidth = 1
            };
            canvas.DrawLine(0, 0, 100, 0, thinLinePaint);

            canvas.Flush();
            using (var save = SKImage.FromBitmap(image))
            using (var data = save.Encode(SKEncodedImageFormat.Png, 100))
            {
                // save the data to a stream
                using (var stream = File.OpenWrite("testSkia0.png"))
                {
                    data.SaveTo(stream);
                }
            }

testSkia0

@JimBobSquarePants
Copy link
Member

There's a potential fix to this but I will need your advice @tocsoft as I don't know whether this is correct.

The issue looks to me like a rounding error. We lose information when a line is only 1px thick so everything is offset when Clipper does it's thing.

offset.Execute(ref tree, width * ScalingFactor / 2);

Adding the following code to the method before scaling fixes this particular issue. The line is placed correctly and is 1px thick.

    if (width <= 1F)
    {
         width += .5F;
    }

test

However, we now have a difference of about 0.3% - 1.6% in fine pen writing with 3 failing tests. The stroke width appears to be the same but the antialiasing is heavier.

Pre
FontShapesAreRenderedCorrectlyWithAPen_Solid900x150_(255,255,255,255)_pen_OpenSans-Regular ttf-50-Sphi-(0,0)

Post
FontShapesAreRenderedCorrectlyWithAPen_Solid900x150_(255,255,255,255)_pen_OpenSans-Regular ttf-50-Sphi-(0,0)

Pre
FontShapesAreRenderedCorrectlyWithAPen_Solid1100x200_(255,255,255,255)_pen_OpenSans-Regular ttf-50-Sphi-(150,50)

Post
FontShapesAreRenderedCorrectlyWithAPen_Solid1100x200_(255,255,255,255)_pen_OpenSans-Regular ttf-50-Sphi-(150,50)

Pre
FontShapesAreRenderedCorrectlyWithAPen_Solid200x150_(255,255,255,255)_pen_SixLaborsSampleAB woff-50-ABAB-(0,0)

Post
FontShapesAreRenderedCorrectlyWithAPen_Solid200x150_(255,255,255,255)_pen_SixLaborsSampleAB woff-50-ABAB-(0,0)

@JimBobSquarePants JimBobSquarePants added the bug Something isn't working label Jun 24, 2020
@JimBobSquarePants
Copy link
Member

JimBobSquarePants commented Jun 25, 2020

Looks like my fix is definitely bad. Here's System.Drawing (GenericSansSerif)

text-test

@tocsoft
Copy link
Member

tocsoft commented Jun 26, 2020

I plan to try to take a look over this issue this weekend, I think I need to create some comparisons with of other libs and see where we differ and how.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants