精确缩放图像

时间:2017-11-14 17:48:20

标签: c# .net resolution scaling imaging

我正在尝试精确地,可预测地将C#中的图像缩放到不同的分辨率,包括上下。当我使用Gimp等外部工具打开生成的图像时,结果不能满足我当前的设置。

public Image Square(Image image, int res) {
    Bitmap sq = new Bitmap(res, res, image.PixelFormat);
    Graphics canvas = Graphics.FromImage(sq);
    canvas.CompositingQuality = CompositingQuality.HighQuality;
    canvas.SmoothingMode = SmoothingMode.None;
    canvas.InterpolationMode = InterpolationMode.Bicubic;
    canvas.DrawImage(sq, 0, 0, res, res);
    return sq;
}

缩小(但远非完美)时结果还可以,但扩展时会产生副作用:

此图片的分辨率为2x2像素。对于所有像素,alpha通道设置为不透明。 2x2 opaque

将其缩放到4x4像素后,结果如下: 4x4 with alpha

显然,C#图形库在缩放图片时引入了透明度。如果给定图像具有透明图片,则此方法仍然有效,因此不能选择删除Alpha通道。

同样,向下缩放图片时,结果图像的边缘也会出现问题,通常是非常暗或透明。

有没有办法规避这种行为?

编辑:我已经尝试过NearestNeighbor只进行缩减,但结果如下:

4x4 nearest neighbor

编辑2:使用WrapMode.TileFlipXY时,透明边缘消失,但红色仅占图像的25%而不是50%:

4x4 tileflipxy

3 个答案:

答案 0 :(得分:2)

您要求bicubic interpolation并且您正在获取它。你想要的是"最近邻居"选项为outlined in the docs

canvas.InterpolationMode = InterpolationMode.NearestNeighbor;

答案 1 :(得分:2)

避免边缘瑕疵的一种方法是包装图像:

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

直接复制/粘贴:

Ghost-borders ('ringing') when resizing in GDI+

答案 2 :(得分:1)

我认为您需要将NearestNeighbor interpolationHalf pixel offset合并。正如类似问题所指出的那样here

canvas.InterpolationMode = InterpolationMode.NearestNeighbor;
canvas.PixelOffsetMode = PixelOffsetMode.Half;