如何用 C# 绘制平滑的图像?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/566245/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to draw smooth images with C#?
提问by
I'm trying to draw images on a C# form (in PictureBoxes, as well as using Graphics.DrawImage()), and am looking for a way to draw them smooth. The images must be a format that supports transparency, so PNG, GIF, SVG, and WMF. C# doesn't support SVG files out of the box, and I haven't found a good third-party library to use (I found SvgNet, but couldn't figure it out).
我正在尝试在 C# 表单上绘制图像(在 PictureBoxes 中,以及使用 Graphics.DrawImage()),并且正在寻找一种方法来平滑地绘制它们。图像必须是支持透明度的格式,例如 PNG、GIF、SVG 和 WMF。C# 不支持开箱即用的 SVG 文件,我还没有找到一个好的第三方库来使用(我找到了 SvgNet,但无法弄清楚)。
I need to draw a WMF file, which C# can do via the Image.FromFile() function, but it's not anti-aliased. I was wondering if there's any way to smooth this out?
我需要绘制一个 WMF 文件,C# 可以通过 Image.FromFile() 函数来完成,但它没有抗锯齿。我想知道有没有什么办法可以解决这个问题?
回答by David
When drawing the image to a canvas, you can change the interpolation mode to something nicer then nearest neighbor to make resized images smooth:
将图像绘制到画布上时,您可以将插值模式更改为比最近邻更好的模式,以使调整大小的图像变得平滑:
Graphics g = ...
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(...);
You'll need to add System.Drawing.Drawing2D to get the InterpolationMode enum.
您需要添加 System.Drawing.Drawing2D 以获取 InterpolationMode 枚举。
Using PictureBox will be a problem - it doesn't expose an InterpolationMode property, so you'll need to roll your own or download one.
使用 PictureBox 将是一个问题 - 它不公开 InterpolationMode 属性,因此您需要自己制作或下载一个。
回答by Jason D
The previous answers, while well intended were only partially correct.
以前的答案虽然是出于好意,但只是部分正确。
What was correct? PictureBox doesn't expose InterpolationMode.
什么是正确的?PictureBox 不公开 InterpolationMode。
What was off base?
什么是基地外?
1) While you can easily set that property in the Paint event from the picture box, in its parent, or via an override in a derived class. . . Either way works and both are just as easy. However, unless SmoothingMode is set, the InterpolationMode will be ignored. You won't get any anti-aliasing without SmoothingMode set to SmoothingMode.AnitAlias.
1) 虽然您可以从图片框、其父级或通过派生类中的覆盖轻松地在 Paint 事件中设置该属性。. . 无论哪种方式都有效,两者都同样简单。但是,除非设置了 SmoothingMode,否则 InterpolationMode 将被忽略。如果没有将 SmoothingMode 设置为 SmoothingMode.AnitAlias,您将不会获得任何抗锯齿。
2) Using a Panel when you've clearly expressed an interest in using the features of PictureBox is the wrong direction to go. You will lack any ability to load, save, or assign images directly to it without explicitly coding those properties. . . Why re-invent the wheel?By deriving off of PictureBox you get all of that for free.
2) 当您明确表示有兴趣使用 PictureBox 的功能时,使用面板是错误的方向。您将无法直接加载、保存或分配图像,而无需对这些属性进行明确编码。. . 为什么要重新发明轮子?通过派生出 PictureBox,您可以免费获得所有这些。
The news gets even better as I've done the hard workfor you and it took me less time than writing this message.
消息变得更好,因为我已经为您完成了艰苦的工作,而且我花费的时间比写这条消息的时间要少。
I've provided two version both of which derive from PictureBox. Firstis a simple example which always uses the best quality rendering possible. This is also the slowest rendering. Secondis a class that allows anyone to set the various rendering parameters via properties off the derived class. Once set these are used in the OnPaint override.
我提供了两个版本,它们都源自 PictureBox。首先是一个简单的例子,它总是使用最好的渲染质量。这也是最慢的渲染。第二个是允许任何人通过派生类的属性设置各种渲染参数的类。一旦设置,这些将用于 OnPaint 覆盖。
public class HighQualitySmoothPictureBox : PictureBox
{
protected override void OnPaint(PaintEventArgs pe)
{
// This is the only line needed for anti-aliasing to be turned on.
pe.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
// the next two lines of code (not comments) are needed to get the highest
// possible quiality of anti-aliasing. Remove them if you want the image to render faster.
pe.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
pe.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic;
// this line is needed for .net to draw the contents.
base.OnPaint(pe);
}
}
...
...
public class ConfigurableQualityPictureBox : PictureBox
{
// Note: the use of the "?" indicates the value type is "nullable."
// If the property is unset, it doesn't have a value, and therefore isn't
// used when the OnPaint method executes.
System.Drawing.Drawing2D.SmoothingMode? smoothingMode;
System.Drawing.Drawing2D.CompositingQuality? compositingQuality;
System.Drawing.Drawing2D.InterpolationMode? interpolationMode;
public System.Drawing.Drawing2D.SmoothingMode? SmoothingMode
{
get { return smoothingMode; }
set { smoothingMode = value; }
}
public System.Drawing.Drawing2D.CompositingQuality? CompositingQuality
{
get { return compositingQuality; }
set { compositingQuality = value; }
}
public System.Drawing.Drawing2D.InterpolationMode? InterpolationMode
{
get { return interpolationMode; }
set { interpolationMode = value; }
}
protected override void OnPaint(PaintEventArgs pe)
{
if (smoothingMode.HasValue)
pe.Graphics.SmoothingMode = smoothingMode.Value;
if (compositingQuality.HasValue)
pe.Graphics.CompositingQuality = compositingQuality.Value;
if (interpolationMode.HasValue)
pe.Graphics.InterpolationMode = interpolationMode.Value;
// this line is needed for .net to draw the contents.
base.OnPaint(pe);
}
}