InterpolationMode HighQualityBicubic introducing artefacts on edge of resized images

前端 未结 3 1708
心在旅途
心在旅途 2021-01-11 18:13

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

Image imgToResize = Image.FromFile(@\"Dejeuner.jpg\");
Siz         


        
相关标签:
3条回答
  • 2021-01-11 18:33

    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");
    
    0 讨论(0)
  • 2021-01-11 18:33

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

    0 讨论(0)
  • 2021-01-11 18:42

    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);
    }
    
    0 讨论(0)
提交回复
热议问题