InterpolationMode HighQualityBicubic introducing artefacts on edge of resized images

独自空忆成欢 提交于 2019-11-30 23:50:38

问题


Using some pretty stock standard C# code to resize an image, and place it on a coloured background

Image imgToResize = Image.FromFile(@"Dejeuner.jpg");
Size size = new Size(768, 1024);
Bitmap b = new Bitmap(size.Width, size.Height);

Graphics g = Graphics.FromImage((Image)b);
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.FillRectangle(Brushes.Green, 0, 0, size.Width, size.Height);

g.DrawImage(imgToResize, new Rectangle(0,150,768, 570));
b.Save("sized_HighQualityBicubic.jpg");

The result has a funny artefact in the 0th and 1st columns of pixels. The 0th column appears to be mixed with the background colour, and the 1st column has been made lighter.

See the top left corner zoomed for high quality bicubic and bicubic.

..and HighQualityBilinear

This forum post appears to be someone with the same problem: DrawImage with sharp edges

The sounds like a bug to me? I can understand why the colours would mix at the top of the resized image. But mixing the colours on the left / right edges doesn't make sense. Does anyone know of a fix to prevent these artefacts?

Update: very similar conversation going on in the comments here: GDI+ InterpolationMode


回答1:


Shamelessly lifting the answer from this question, I found this fixes it:

using (ImageAttributes wrapMode = new ImageAttributes())
{
    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
    g.DrawImage(input, rect, 0, 0, input.Width, input.Height, GraphicsUnit.Pixel, wrapMode);
}



回答2:


Below is the resulting image of typical HighQualityBicubic resizing (drawn over white background).

You can see semi-transparent pixels at edge lines. You can call it a bug. I think it is just a technical detail of the GDI+. And it is simple to workaround this artifact.

1) Prevent anti-aliasing.

...
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
// add below line
g.CompositingMode = CompositingMode.SourceCopy;
...

With CompositingMode.SourceCopy result image will show visible outline but not anti-aliased with background pixels.

2) Crop semi-transparent area

You can ignore those semi-transparent pixels altogether.

Image imgToResize = Image.FromFile(@"Dejeuner.jpg");
Size size = new Size(768, 1024);
Bitmap b = new Bitmap(size.Width, size.Height);

Graphics g = Graphics.FromImage((Image)b);
g.FillRectangle(Brushes.Green, 0, 0, size.Width, size.Height);

Bitmap b2 = new Bitmap(768 + 8, 570 + 8);
{
    Graphics g2 = Graphics.FromImage((Image)b2);
    g2.Clear(Color.White);
    g2.InterpolationMode = InterpolationMode.HighQualityBicubic;
    g2.DrawImage(imgToResize, new Rectangle(2, 2, 768 + 4, 570 + 4));
}

g.CompositingMode = CompositingMode.SourceCopy;
g.DrawImage(b2, 0, 150, new Rectangle(4, 4, 768, 570), GraphicsUnit.Pixel);
b.Save("sized_HighQualityBicubic.jpg");



回答3:


Set the PixelOffsetMode property to HighQuality to get a better blend with the background at the edges.



来源:https://stackoverflow.com/questions/4772273/interpolationmode-highqualitybicubic-introducing-artefacts-on-edge-of-resized-im

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