2012-07-17 57 views
1

我正在嘗試輸入流(圖像的zip文件)並提取每個文件。但是我必須在保存之前降低每幅圖像的質量(如果質量爲< 100)。我曾嘗試以下但它從來沒有壓縮形象:在保存前降低圖像/流的質量

public void UnZip(Stream inputStream, string destinationPath, int quality = 80) { 
    using (var zipStream = new ZipInputStream(inputStream)) { 
     ZipEntry entry; 

     while ((entry = zipStream.GetNextEntry()) != null) { 
      var directoryPath = Path.GetDirectoryName(destinationPath + Path.DirectorySeparatorChar + entry.Name); 
      var fullPath = directoryPath + Path.DirectorySeparatorChar + Path.GetFileName(entry.Name); 

      // Create the stream to unzip the file to 
      using (var stream = new MemoryStream()) { 
       // Write the zip stream to the stream 
       if (entry.Size != 0) { 
        var size = 2048; 
        var data = new byte[2048]; 

        while (true) { 
         size = zipStream.Read(data, 0, data.Length); 

         if (size > 0) 
          stream.Write(data, 0, size); 
         else 
          break; 
        } 
       } 

       // Compress the image and save it to the stream 
       if (quality < 100) 
        using (var image = Image.FromStream(stream)) { 
         var info = ImageCodecInfo.GetImageEncoders(); 
         var @params = new EncoderParameters(1); 
         @params.Param[0] = new EncoderParameter(Encoder.Quality, quality); 
         image.Save(stream, info[1], @params); 
        } 
       } 

       // Save the stream to disk 
       using (var fs = new FileStream(fullPath, FileMode.Create)) { 
        stream.WriteTo(fs); 
       } 
      } 
     } 
    } 
} 

我會很感激,如果有人能告訴我我做錯了什麼。任何關於整理它的建議都會被讚賞,因爲代碼的長大變得醜陋。謝謝

+0

你的問題和你的代碼是矛盾的。 「解壓縮」意味着解壓縮,而你的問題是關於爲什麼不壓縮。你能更清楚地回答你的問題嗎? – 2012-07-17 15:14:43

+0

嗨,彼得,我需要解壓zip文件,然後分別壓縮生成的文件。這可以節省磁盤空間。我認爲斯科特的答案會幫助。 – nfplee 2012-07-17 19:02:05

回答

2

你真的不應該使用相同的流來保存壓縮的圖像。 MSDN文檔清楚地說:「不要將圖像保存到用於構建圖像的相同流中,否則可能會損壞流。」 (MSDN Article on Image.Save(...)

using (var compressedImageStream = new MemoryStream()) 
{ 
    image.Save(compressedImageStream, info[1], @params); 
} 

此外,什麼文件格式,你編碼爲?你還沒有指定。你只是找到了第二個編碼器。你不應該依賴結果的順序。搜索特定的編碼解碼器來代替:

var encoder = ImageCodecInfo.GetImageEncoders().Where(x => x.FormatID == ImageFormat.Jpeg.Guid).SingleOrDefault() 

...不要忘記檢查,如果編碼器沒有您的系統上存在:

if (encoder != null) 
{ .. } 

質量參數沒有意義適用於所有文件格式。我假設你可能正在使用JPEG?另外,請記住100%JPEG質量!=無損圖像。您仍然可以使用質量= 100進行編碼並減少空間。

+0

謝謝你的工作。再次感謝關於編碼的其他建議。 – nfplee 2012-07-18 10:58:56

1

從zip流中提取圖像後,沒有代碼可以壓縮圖像。您所做的只是將解壓縮的數據放入MemoryStream中,然後根據質量信息(可能壓縮或不壓縮圖像,取決於編解碼器)將圖像寫入同一個流中。我首先建議不要寫入您正在閱讀的同一個流。此外,您從Encoder.Quality屬性中獲得的「壓縮」取決於圖像的類型 - 您尚未提供任何細節。如果圖像類型支持壓縮並且傳入圖像質量低於100,則不會縮小圖像尺寸。此外,你還沒有提供任何有關這方面的信息。長話短說,你沒有提供足夠的信息給任何人給你一個真正的答案。

+0

它們通過'info [1]'指定目標文件格式,它只是返回系統中找到的第二個編碼器...通常是JPEG編碼器。 – Scott 2012-07-17 15:42:23

+0

我不會建議依賴於此。如果原始圖像流的JPEG圖像質量已經低於質量(默認爲80),那麼JPEG不能壓縮比已經存在的更多的圖像 - 因此會出現不壓縮任何東西的情況 – 2012-07-17 15:56:09

+0

我會'建議依靠那個。你說得對。您必須考慮圖像可能已經採用類似或更低質量設置的JPEG編碼。 – Scott 2012-07-18 14:54:22

相關問題