[英]Resizing Image Quality Reduction
我編寫了一個簡單的 PhotoEditor 幫助程序類來縮小和裁剪上傳到我網站的圖像。 一切正常,但當圖像保存到文件時,我發現質量不盡如人意。 我已經閱讀了您可以調整的不同設置,下面是我調整大小的設置,裁剪是相同的。
public Image ResizeImage(Image imgToResize, Size size)
{
int sourceWidth = imgToResize.Width;
int sourceHeight = imgToResize.Height;
float nPercentW = (size.Width/(float) sourceWidth);
float nPercentH = (size.Height/(float) sourceHeight);
float nPercent = nPercentH < nPercentW ? nPercentH : nPercentW;
var destWidth = (int) (sourceWidth*nPercent);
var destHeight = (int) (sourceHeight*nPercent);
var src = imgToResize;
using (var dst = new Bitmap(destWidth, destHeight, imgToResize.PixelFormat))
{
dst.SetResolution(imgToResize.HorizontalResolution, imgToResize.VerticalResolution);
using (var g = Graphics.FromImage(dst))
{
var mime = GetMimeType(imgToResize);
ImageFormat format;
if (mime == "image/gif" || mime == "image/png")
{
//convert all gif to png, better resize quality
g.SmoothingMode = SmoothingMode.AntiAlias;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.DrawImage(src, 0, 0, dst.Width, dst.Height);
format = ImageFormat.Png;
}
else
{
//jpeg
g.CompositingQuality = CompositingQuality.HighQuality;
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.SmoothingMode = SmoothingMode.HighQuality;
g.PixelOffsetMode = PixelOffsetMode.HighQuality;
format = ImageFormat.Jpeg;
}
g.DrawImage(src, 0, 0, dst.Width, dst.Height);
// At this point the new bitmap has no MimeType
// Need to output to memory stream
var m = new MemoryStream();
dst.Save(m, format);
var img = Image.FromStream(m);
return img;
}
}
}
如您所見,我正在使用建議的插值、平滑等設置。我還保存了質量為 100 的 jpeg。
生成的圖像有明顯的模糊和偽影,即使將其尺寸縮小到原始尺寸的 75% 也是如此。 我環顧四周,這是推薦的方式。 我找到了一種調整大小的簡單方法,並決定試一試。
Bitmap NewImg = new Bitmap(original, new Size(387,257));
editor.SaveImage(@"C:\simpleResize.jpg", NewImg, ImageFormat.Jpeg);
令人驚訝的是,這會產生更好的圖像,盡管它的內存占用要大 30%。
我的問題是,有什么區別以及我在調整大小例程中缺少什么設置可以解釋更丑陋的結果。 我想讓我的調整大小例程產生與簡單調整大小完全相同的結果。
非常感謝您的幫助。 這是我第一次涉足圖像處理。
編輯
簡單調整大小 (82KB)
簡單的 http://img189.imageshack.us/img189/2137/simpleresize.jpg
我的調整大小 (55KB)
我找到了這個示例代碼片段(抱歉,我忘記了來源)可能對您有幫助:
// Create parameters
EncoderParameters params = new EncoderParameters (1);
// Set quality (100)
params.Param[0] = new EncoderParameter(Encoder.Quality, 100);
// Create encoder info
ImageCodecInfo codec = null;
foreach (ImageCodecInfo codectemp in ImageCodecInfo.GetImageDecoders())
{
if (codectemp.MimeType == "image/jpeg")
{
codec = codectemp;
break;
}
}
// Check
if (codec == null)
throw new Exception("Codec not found for image/jpeg");
// Save
image.Save(filename, codec, params);
我的第一個想法是 .NET 的 jpeg 編碼器即使在最高質量設置下也使用色度子采樣,因此顏色信息以一半的分辨率存儲。 據我所知,該設置是硬編碼的。 但這並不能解釋為什么你會在第二個例子中獲得更好的質量。 除非可能在第 2 次它沒有使用抗鋸齒,提供更清晰(但質量較低)的圖像並且偽影沒有被注意到。
編輯:dst.Save(m, format); 看起來像你的問題。 您在那里將其編碼為 jpeg,具有默認質量(不是 100%),然后立即將其解碼回圖像。 dst 已經是一個 Image(Bitmap 類繼承自 Image),因此您可以按原樣返回它
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.