调整图像大小 - 有时质量很差?
我正在将一些图像的大小调整为用户的屏幕分辨率; 如果长宽比错误,则应剪切图像。 我的代码如下所示:
protected void ConvertToBitmap(string filename)
{
var origImg = System.Drawing.Image.FromFile(filename);
var widthDivisor = (double)origImg.Width / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Width;
var heightDivisor = (double)origImg.Height / (double)System.Windows.Forms.Screen.PrimaryScreen.Bounds.Height;
int newWidth, newHeight;
if (widthDivisor < heightDivisor)
{
newWidth = (int)((double)origImg.Width / widthDivisor);
newHeight = (int)((double)origImg.Height / widthDivisor);
}
else
{
newWidth = (int)((double)origImg.Width / heightDivisor);
newHeight = (int)((double)origImg.Height / heightDivisor);
}
var newImg = origImg.GetThumbnailImage(newWidth, newHeight, null, IntPtr.Zero);
newImg.Save(this.GetBitmapPath(filename), System.Drawing.Imaging.ImageFormat.Bmp);
}
在大多数情况下,这工作得很好。 但对于某些图像,结果的质量极差。 看起来会被调整到非常小的尺寸(缩略图尺寸)并再次放大。但是图像的分辨率是正确的。 我能做些什么?
原始图像示例: 替代文本 http://img523.imageshack.us/img523/1430/naturaerowoods.jpg< /a>
注意:我有一个 WPF 应用程序,但我使用 WinForms 函数来调整大小,因为它更容易,而且我已经需要引用 System.Windows.Forms 作为托盘图标。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(10)
将方法的最后两行更改为:
Change the last two lines of your method to this:
我目前无法查看 .NET 源代码,但问题很可能出在
Image.GetThumbnailImage
方法中。 甚至 MSDN 也表示“当请求的缩略图图像大小约为 120 x 120 像素时,它效果很好,但如果您从嵌入缩略图的图像请求大缩略图图像(例如 300 x 300),则可能会出现这样的情况:缩略图质量明显下降”。 对于真正的大小调整(即不是缩略图),您应该使用 Graphics.DrawImage 方法。 如果需要,您可能还需要使用Graphics.InterpolationMode
以获得更好的质量。I cannot peek into the .NET source at the moment, but most likely the problem is in the
Image.GetThumbnailImage
method. Even MSDN says that "it works well when the requested thumbnail image has a size of about 120 x 120 pixels, but it you request a large thumbnail image (for example, 300 x 300) from an Image that has an embedded thumbnail, there could be a noticeable loss of quality in the thumbnail image". For true resizing (i.e. not thumbnailing), you should use theGraphics.DrawImage
method. You may also need to play with theGraphics.InterpolationMode
to get a better quality if needed.如果您不创建缩略图,那么使用名为
GetThumbnailImage
的方法可能不是一个好主意...有关其他选项,请查看 这篇 CodeProject 文章。 具体来说,它创建一个新图像,为其创建一个
Graphics
并将插值模式设置为HighQualityBicubic
并将原始图像绘制到图形上。 至少值得一试。If you're not creating a thumbnail, using a method called
GetThumbnailImage
probably isn't a good idea...For other options, have a look at this CodeProject article. In particular, it creates a new image, creates a
Graphics
for it and sets the interpolation mode toHighQualityBicubic
and draws the original image onto the graphics. Worth a try, at least.如 MSDN 所示,
GetThumbnailImage()
并非旨在进行任意图像缩放。 任何超过 120x120 的内容都应手动缩放。 请尝试以下操作:Edit
需要澄清的是,尽管您没有任何控制权,但
Bitmap
构造函数的重载会调用Graphics.DrawImage
超过插值。As indicated on MSDN,
GetThumbnailImage()
is not designed to do arbitrary image scaling. Anything over 120x120 should be scaled manually. Try this instead:Edit
As a point of clarification, this overload of the
Bitmap
constructor callsGraphics.DrawImage
, though you do not have any control over the interpolation.而不是这个代码:
使用这个:
instead of this code:
use this one :
例如,原始图像是 JPG,调整大小后的图像是 PNG。 您是否有意在格式之间进行转换? 在不同有损压缩方案之间切换可能会导致质量损失。
For examples, the original image is JPG and the resized image is PNG. Are you converting between formats on purpose? Switching between different lossey compression schemes can cause quality loss.
调整图像大小时是增大还是减小图像的大小? 如果您要从较小的图像创建较大的图像,这种降级是可以预料的。
Are you increasing or decreasing the size of the image when you resize it? If you are creating a larger image from a smaller one, this sort of degradation is to be expected.
如果放大图像肯定会降低质量。
Images will definitely be degraded if you enlarge them.
某些相机将调整大小的缩略图放入文件本身中,大概是为了在设备本身上进行预览。
GetThumbnail 方法实际上获取嵌入在图像文件中的缩略图图像,而不是获取更高分辨率的方法。
简单的解决方案是在进行调整大小或其他操作之前欺骗 .Net 丢弃缩略图信息。 像这样......
如果您尝试调整约束比例的大小,我在 System.Drawing.Image 上编写了一个扩展方法,您可能会发现它很方便。
Some camera's put a resized thumbnail into the file itself presumably for preview purposes on the device itself.
The GetThumbnail method actually gets this Thumbnail image which is embedded within the image file instead of getting the higher res method.
The easy solution is to trick .Net into throwing away that thumbnail information before doing your resize or other operation. like so....
If you are attempting to resize constraining proportions I wrote an extension method on System.Drawing.Image that you might find handy.
这将根据以下因素而有很大差异:
This is going to vary widely based on the following factors: