2011-11-17 131 views
1

我在該網站有一個用戶畫廊,訪客可以上傳一些圖像。上傳圖片後,應調整到一些預定義的預設。另外原圖也應該保存。所有工作正常pngbmp圖像格式。但如果我上傳gif格式或jpeg與優勢的一種顏色上傳原始圖像似乎被壓縮。圖像上傳沒有質量損失

例如:

原文:
Original image

上傳:
Uploaded image

我看一遍在谷歌搜索,並發現了一些例子,說明如何上傳圖片的權利。 最後我已經寫了一個方法:

void UploadImagePreset(Image image, ImageFormat imgFormat, string imgPath) 
{ 
    using (var uploadStream = imageUploader.CreateUploadStream(imagePath)) 
    { 
     var newWidth = image.Width; 
     var newHeight = image.Height; 
     using (var outBitmap = new Bitmap(newWidth, newHeight)) 
     { 
      using (var outGraph = Graphics.FromImage(outBitmap)) 
      { 
       outGraph.CompositingQuality = CompositingQuality.HighQuality; 
       outGraph.SmoothingMode = SmoothingMode.HighQuality; 
       outGraph.PixelOffsetMode = PixelOffsetMode.HighQuality; 
       outGraph.InterpolationMode = InterpolationMode.HighQualityBicubic; 

       var imageRect = new Rectangle(0, 0, newWidth, newHeight); 
       outGraph.DrawImage(image, imageRect); 

       outBitmap.Save(uploadStream, imgFormat); 
      } 
     } 
    } 
} 

但它並沒有幫助。上傳的圖像與上述相同。 我已經tryied像這樣指定結果圖像的qaulity:

var encoderParameters = new EncoderParameters(); 
var encoderParameter = new EncoderParameter(Encoder.Quality, 100); 
encoderParameters.Param[0] = encoderParameter; 
var encoder = ImageCodecInfo.GetImageEncoders() 
    .Where(e => e.FormatID == imgFormat.Guid) 
    .FirstOrDefault(); 
outBitmap.Save(uploadStream, encoder, encoderParameters); 

它沒有工作過。另外當我上傳jpeg圖像時發生異常。

有沒有壓縮或調整大小的上傳圖像的方法?我花了幾個小時試圖解決這個問題,並堅持下去。

+0

目前還不清楚 - 上傳過程是怎麼回事?如果它僅僅來自沒有額外客戶端代碼的瀏覽器,則應該獲取客戶端上的確切文件 - 此時,您的問題與上傳(或ASP.NET)沒有關係,並且只是*做調整大小。 –

+0

我使用FileUpload控件,沒有任何額外的客戶端代碼 –

+0

正確的,所以首先驗證,如果你保存了上傳的文件 - 根本不處理它* - 你最終會得到完全相同的文件。當你向自己證明了這一點時,你可以將上傳部分排除在等式之外。將問題縮小到儘可能小的區域。 –

回答

7

您正在通過Image類上傳的圖像 - 這是一個新的圖像,基於傳入的流。

然後使用一些默認參數保存,這將不再反映原始圖像。

您應該簡單地將傳入的流保存到磁盤 - 這將導致原始圖像的精確副本。

這樣的(.NET 4.0):

using (var uploadStream = imageUploader.CreateUploadStream(imagePath)) 
{ 
    using(var fileStream = new FileStream(imgPath, FileMode.Create)) 
    { 
     uploadStream.CopyTo(fileStream); 
    } 
} 

或(預.NET 4.0):

using (var uploadStream = imageUploader.CreateUploadStream(imagePath)) 
{ 
    using(var fileStream = new FileStream(imgPath, FileMode.Create)) 
    { 
     byte[] buffer = new byte[32768]; 
     int read; 
     while ((read = uploadStream.Read(buffer, 0, buffer.Length)) > 0) 
     { 
      fileStream.Write(buffer, 0, read); 
     } 
    } 
} 

this answer改編。

+0

我使用.Net 3.5。 Stream類在此版本的框架中沒有CopyTo方法。 –

+0

@IgorBlinnikov - 看到這個另一個選項:http://stackoverflow.com/questions/230128/best-way-to-copy-between-two-stream-instances-c-sharp – Oded

+0

謝謝你,Oded。你的回答非常有幫助。問題是我首先從Stream創建了Image對象,然後保存了Stream。即使我保存原始流,但不保存圖像對象,使用流對象操作也會將噪聲添加到結果圖像中。上傳後(在創建Image對象之前)將Streaming直接保存爲文件解決了我的問題。 –

1

我建議使用圖像編解碼器(您的第二個例子)進行無損圖像壓縮。

有了一個很小的代碼修改,我建議你試試這個:

Bitmap bm = (Bitmap)Image.FromFile(filePath); 
ImageCodecInfo[] codecs = ImageCodecInfo.GetImageEncoders(); 
ImageCodecInfo codecInfo = null; 
foreach (ImageCodecInfo codec in codecs) 
{ 
    if (codec.MimeType == "image/jpeg") 
     codecInfo = codec; 
} 
EncoderParameters ep = new EncoderParameters(); 
ep.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)100); 
bm.Save("C:\\quality" + x.ToString() + ".jpg", codecInfo, ep); 

希望這會有所幫助。

+0

我必須按原樣上傳圖片。我無法將格式更改爲jpeg。如果用戶上傳了* .png圖片,則應將其保存爲png。 –

+0

這對我來說非常合適。相同的+1。 :) –