开发者

InterpolationMode HighQualityBicubic introducing artefacts on edge of resized images

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.

InterpolationMode HighQualityBicubic introducing artefacts on edge of resized images

InterpolationMode HighQualityBicubic introducing artefacts on edge of resized images

..and HighQualityBilinear

InterpolationMode HighQualityBicubic introducing artefacts on edge of resized images

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 wou开发者_开发问答ld 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


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);
}


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

InterpolationMode HighQualityBicubic introducing artefacts on edge of resized images

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");


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

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜