Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 插值模式高质量双三次在调整大小的图像边缘引入伪影_C#_Graphics_System.drawing - Fatal编程技术网

C# 插值模式高质量双三次在调整大小的图像边缘引入伪影

C# 插值模式高质量双三次在调整大小的图像边缘引入伪影,c#,graphics,system.drawing,C#,Graphics,System.drawing,使用一些漂亮的标准C#代码调整图像大小,并将其放置在彩色背景上 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.

使用一些漂亮的标准C#代码调整图像大小,并将其放置在彩色背景上

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");
在第0列和第1列像素中有一个有趣的伪影。第0列似乎与背景色混合,第1列变得更亮

请参见左上角缩放的高质量双三次曲线和双三次曲线

…和高质量双线性

此论坛帖子似乎有相同的问题:

对我来说这听起来像个虫子?我能理解为什么颜色会在调整尺寸后的图像顶部混合。但是在左/右边缘混合颜色是没有意义的。有人知道有什么办法可以阻止这些文物吗


更新:在这里的评论中进行了非常类似的对话:

下面是典型的
高质量双三次缩放的结果图像(在白色背景上绘制)

可以在边缘线处看到半透明像素。你可以称之为bug。我认为这只是GDI+的一个技术细节。解决这个工件很简单

1) 防止抗锯齿。 使用
合成模式。SourceCopy
结果图像将显示可见的轮廓,但不会与背景像素消除混叠

2) 作物半透明区 您可以完全忽略这些半透明像素

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

将PixelOffsetMode属性设置为HighQuality,以便在边缘与背景更好地融合。

不知羞耻地从中提取答案,我发现这解决了问题:

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

它将背景与图像一起消除混叠。想法是获得尽可能高质量的平滑。一些人称之为bug,另一些称之为特性。不管怎样,你的问题似乎已经在你链接的论坛帖子中得到了回答。你试过高质量双线性吗?用高质量双线性更新了问题。论坛线程只提到了一个非托管修复,一位发帖人同意这是“GDI+中的一个长期缺陷,我想是由于一些懒惰的实现者未能正确处理边界情况造成的”。我的问题与这个问题重复:。我很高兴我的问题被删除/关闭+1 Microsoft在下面的操作文章中明确推荐您的第一个解决方案:。这篇文章还解释了它如何既不是bug,也不是“技术工件”。使用背景消除图像的锯齿是设计的默认行为。如果你想要别的东西,你必须要它。当你在一个更大的背景上画一个图像时,消除混叠是有意义的。如果将图像的边缘放置在背景边缘上,或者将背景放置在与图像大小相同的边缘上,这是否有意义,这是有争议的。我对第2步的理解-
Bitmap
b2获取原始图像@2,2。最终的绘图
DrawImage
从b2@4,4处剪切。沿顶部和左侧边缘是否会丢失2px?我知道那是透明像素“活的”,但如果任何原始图像丢失,我所做的将不起作用。@russau,我想这取决于你的决定。您可以将
b2
位图保存到文件中,并与原始位图进行比较。因为它是插值的,所以不清楚这些半透明像素是否属于我们预期的目标图像。仅供参考,这里有一个删除透明像素的好方法:
using (ImageAttributes wrapMode = new ImageAttributes())
{
    wrapMode.SetWrapMode(WrapMode.TileFlipXY);
    g.DrawImage(input, rect, 0, 0, input.Width, input.Height, GraphicsUnit.Pixel, wrapMode);
}