2009-07-21 173 views
2

我已經編寫了一個簡單的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; 
      } 
     } 
    } 

正如你可以看到我使用插值建議的設置,平滑等等。我還保存JPEG質量100

所得到的圖像具有明顯的模糊和文物甚至向下調整時其原始尺寸的75%。我環顧四周,這是推薦的方式。我找到了一個簡單的方法來調整大小,並決定放棄。

Bitmap NewImg = new Bitmap(original, new Size(387,257)); 
editor.SaveImage(@"C:\simpleResize.jpg", NewImg, ImageFormat.Jpeg); 

令人驚訝的是,這會產生更好的圖像,儘管它的內存佔用空間大了30%以上。

我的問題是,有什麼區別,我在我的調整大小例程,缺少什麼設置可以解釋醜陋的結果。我喜歡讓我的調整大小例程產生與簡單調整大小完全相同的結果。

非常感謝您的幫助。這是我第一次進入圖像處理領域。

編輯

簡單調整大小(82KB)

simple http://img189.imageshack.us/img189/2137/simpleresize.jpg

我調整大小(55KB)

complex http://img12.imageshack.us/img12/4023/complexresize.jpg

+1

dst.Save(m,format);看起來像你的問題。您將它編碼爲jpeg,默認質量(不是100%),然後立即將其解碼爲圖像。 dst已經是一個Image(位圖類繼承自Image),所以你可以直接返回它。 – David 2009-07-22 05:17:18

+0

嗨大衛。你是對的。我在這一步背後的推理是,mimetype是最終圖像的一部分。我暫時將該圖像存儲在會話中,並希望能夠稍後檢索它。如果您更新答案,請將其標記爲已回答。 – madcapnmckay 2009-07-22 12:01:38

回答

2

我首先想到的是,.NET的JPEG編碼器使用色度甚至在最高質量的settin下進行二次取樣g,因此顏色信息以半分辨率存儲。據我所知,該設置是硬編碼的。但這並不能解釋爲什麼你會在第二個例子中獲得更好的質量。除非在第二天它沒有使用抗鋸齒功能,否則會產生更清晰(但質量更低)的圖像,而且這些工件未被發現。

編輯:dst.Save(m,format);看起來像你的問題。您將它編碼爲jpeg,默認質量(不是100%),然後立即將其解碼爲圖像。 DST已經是影像(Bitmap類從圖片繼承),所以你可以只返回它就好了

+0

感謝您的快速響應。我試圖改變AA的設置,看看它是否有幫助,但它似乎不是人工製品的原因。我在簡單的調整大小和複合體之間翻轉了四分之一,並且僅在複合體上存在人工製品。 – madcapnmckay 2009-07-21 23:04:12

4

我發現這個代碼示例片段(對不起,我忘了出處),可以幫助你:

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