Graphics - Drawing lines are not even. Rounding errors converting single to integer?

97 views Asked by At

See this link/picture. https://proscan.org/graphics%20rounding%20errors.png

The lines are not uniform Some are thinner and some are wider. The pattern changes when changing the form width. Using NET Framework 4.8.

Code to replicate problem:

    protected override void OnPaint(PaintEventArgs e)
    {
     
        Graphics g = e.Graphics;
        Color c;
        int offsetY;

        g.DrawString("Method 1 - Using ScaleTransform", this.Font, Brushes.Black, 10, 15);
        g.DrawString("Method 2 - Using ScaleTransform and bitmap", this.Font, Brushes.Black, 10, 100);
        g.DrawString("Method 3 - Proves it's not a ScaleTransform issue" + Environment.NewLine + "as not using ScaleTransform and doing the scaling manualy", this.Font, Brushes.Black, 10, 185);

        g.ScaleTransform(System.Convert.ToSingle(this.Width / (double)150), 1);

        // Method 1 - Using ScaleTransform
        offsetY = 35;
        for (int row = 0; row <= 49; row++)
        {
            for (int col = 0; col <= 99; col++)
            {
                if (col % 2 == 0)
                    c = Color.SkyBlue;
                else
                    c = Color.Black;
                g.FillRectangle(new SolidBrush(c), col + 10, row + offsetY, 1, 1);
            }
        }

        // Method 2 - Using ScaleTransform and bitmap
        offsetY = 120;
        g.InterpolationMode = InterpolationMode.NearestNeighbor; // Without this, lines appear even but are burry (lines blended together)
        using (Bitmap bmp = new Bitmap(100, 50))
        {
            using (Graphics g1 = Graphics.FromImage(bmp))
            {
                for (int row = 0; row <= 49; row++)
                {
                    for (int col = 0; col <= 99; col++)
                    {
                        if (col % 2 == 0)
                            c = Color.SkyBlue;
                        else
                            c = Color.Black;
                        g1.FillRectangle(new SolidBrush(c), col, row, 1, 1); // Same effect using SetPixel(col, row, c)
                    }
                }
            }
            g.DrawImage(bmp, new Rectangle(10, offsetY, bmp.Width, bmp.Height), 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel);
        }


        // Method 3 - Proves it's not a ScaleTransform issue as not using ScaleTransform and doing the scaling manualy
        offsetY = 220;
        g.ResetTransform();
        for (int row = 0; row <= 49; row++)
        {
            for (int col = 0; col <= 99; col++)
            {
                if (col % 2 == 0)
                    c = Color.SkyBlue;
                else
                    c = Color.Black;
                g.FillRectangle(new SolidBrush(c), System.Convert.ToSingle((col + 10) * (this.Width / (double)150)), System.Convert.ToSingle(row + offsetY), System.Convert.ToSingle(1 * (this.Width / (double)150)), System.Convert.ToSingle(1 * (this.Height / (double)150)));
            }
        }

        base.OnPaint(e);
    }

I tried various InterpolationMode modes, and putting the lines in a bitmap and drawing the bitmap. I expected the lines width to be uniform

0

There are 0 answers