【问题标题】:Precisely scale image精确缩放图像
【发布时间】:2017-11-14 17:48:20
【问题描述】:

我正在尝试将 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 通道设置为对所有像素不透明。

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

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

同样,缩小图片时,生成的图片的边缘也会出现问题,通常要么很暗,要么很透明。

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


编辑:我已经尝试过 NearestNeighbor 仅用于缩小规模,但结果如下:


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

【问题讨论】:

  • 只有 NearestNeighbor 可以避免插值伪影。不要忘记更改 PixelOffsetMode。

标签: c# .net resolution scaling imaging


【解决方案1】:

你要求bicubic interpolation,你得到了它。你想要的是outlined in the docs的“最近邻居”选项:

canvas.InterpolationMode = InterpolationMode.NearestNeighbor;

【讨论】:

  • 感谢您的回答!我用结果更新了我的问题,但离我想要的位置还很远。
  • 不知何故,我认为您有一个 4x4 图像,其中包含 3x3 的彩色像素,两侧有一个像素的边距是透明的。
  • 是的,这正是我将模式更改为 NearestNeighbor 时得到的结果。
【解决方案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+

【讨论】:

  • 感谢您的回答。我将结果添加到我的问题中,这仍然不是我想要实现的目标。
  • 您是否使用双三次和环绕模式?它应该解决双三次缩放的边缘伪影问题,这是您所问的,但显然看起来与最近邻缩放不同。
  • 谢谢,这确实有帮助!不过,我更喜欢NearestNeighborTileFlipXY 的组合。
【解决方案3】:

我相信您需要将 NearestNeighbor interpolationHalf pixel offset 结合起来。正如在类似问题here中指出的那样。

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

【讨论】:

  • 谢谢,这似乎终于奏效了!我可能会使用它来缩小尺寸并使用不同的插值模式进行放大。让我在接受你的答案之前做一些测试。
  • @just.me 听起来不错,但您真的需要更多像素吗?也许您可以更改图像的 dpi?
  • 很遗憾,是的。我们使用的算法要求所有图像具有完全相同的分辨率。
猜你喜欢
  • 2013-12-16
  • 2020-12-02
  • 2012-09-26
  • 1970-01-01
  • 2011-07-06
  • 2011-01-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多