DrawImage resized image too small

白昼怎懂夜的黑 提交于 2019-12-17 06:55:09

问题


When I draw an image using Graphics.DrawImage and draw it at a bigger size than the original image, it ends up being a bit too small. You can see this in the following picture:

The green lines shouldn't be visible and are not part of the image. Rather they get drawn behind the image and the image should cover them.

How can I draw an image with the exact right size?

EDIT: I draw the green part with the same rectangle I pass into the DrawImage call, with the exact dimensions of how big the image should be. So no flaw in my values (I think).

EDIT 2: I draw the green rectangle using FillRectangle, so no pen calculations need to be done. Also, I logged the values that I pass into the rectangle for both the image and the green fill, and the values are correct. It's just the image that's off. I will post code later, as I'm not at my computer at the moment.

EDIT 3: This is the code I use to render the images:

// This is for zooming
public readonly float[] SCALES = { 0.05f, 0.1f, 0.125f, 0.25f, 0.333f, 0.5f, 0.667f, 0.75f, 1.0f, 1.25f, 1.5f, 1.75f, 2.0f, 2.5f, 3.0f, 3.5f, 4.0f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f, 10.0f, 12.0f, 15.0f, 20.0f, 30.0f, 36.0f };
private int scaleIndex = 8;

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);

    float ScaleFactor = SCALES[scaleIndex];

    e.Graphics.InterpolationMode = ScaleFactor < 1 ? InterpolationMode.Bicubic : InterpolationMode.NearestNeighbor;

    Image im = Properties.Resources.TSprite0;

    for (int y = 0; y < TilesVertical; y++)
    {
        for (int x = 0; x < TilesHorizontal; x++)
        {
            float sx = im.Width * ScaleFactor;
            float sy = im.Height * ScaleFactor;
            Point p = new Point((int)(-scrollPosition.X + sx * x), (int)(-scrollPosition.Y + sy * y));
            Size s = new Size((int)Math.Floor(sx), (int)Math.Floor(sy));

            // The green rectangle in the background should be the same size as the image
            e.Graphics.FillRectangle(Brushes.Lime, new Rectangle(p, s));
            e.Graphics.DrawImage(im, new Rectangle(p, s), 0, 0, 16, 16, GraphicsUnit.Pixel);
        }
    }

    im.Dispose();
}

EDIT 4: Also note that the image seems to be cropped on the left and top instead of resized. Take a look at this comparison of the original image upscaled in Photoshop and then how GDI+ renders it:


回答1:


The issue happens when scaling to 2x or larger.

Looks like the whole problem is caused by the wrong default PixelOffsetMode.

By offsetting pixels during rendering, you can improve render quality at the cost of render speed.

Setting it to

g.PixelOffsetMode = PixelOffsetMode.Half;

makes it go away for me.

Setting it to

g.PixelOffsetMode = PixelOffsetMode.HighQuality;

also works fine.

Default, None and HighSpeed cause the image to be rendered a little to the left and up.

Often you will also want to set InterpolationMode.NearestNeighbor.



来源:https://stackoverflow.com/questions/50419325/drawimage-resized-image-too-small

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!