2010-12-11 99 views
15

我需要壓縮或至少降低用戶上傳到我的網站的一些png圖像的質量。我已經調整過它的大小,但對於圖像大小並沒有太大的作用。C#:尋求PNG壓縮算法/庫

爲.net 4.0或以下版本尋找一個PNG /圖像壓縮或質量損失算法或庫。


這是怎麼了我目前保存/轉換我的圖片:

Image mainImg = ImageHelper.ResizeImage(bmp, 600, 500, false); 
mainImg.Save(filePath, System.Drawing.Imaging.ImageFormat.Png); 
+2

「for .net 4.0 or under」:對不起,我只有一個用於.NET 5.0;) – 2010-12-12 00:13:49

+0

出於好奇你對.NET 5有什麼回答? – Dylan 2012-08-07 19:25:28

+0

我敢打賭,會有一些僅基於4.5 :) – 2012-08-07 21:16:24

回答

22

不幸的是,.NET(和GDI +,其.NET圖形庫是建立在)不支持任何PNG編碼參數。實際上,如果您使用PNG編碼器Clsid在圖像上調用GetEncoderParameterList,則會出現「未實現」異常。

更不幸的是,ImageFormat和ImageCodecInfo都是密封類,你不能只是添加新的編解碼器,以.NET本來可以訪問。微軟在這一球上放下了球。

這意味着你的替代品,在降低受虐狂的順序: 1)實現你自己的.NET實現了RFC 2083保存功能, 2)實現基於關閉的libpng移植到一個保存功能。NET, 3)調用直接從libpng構建的非託管代碼

libpng擁有出色的文檔並且在可用性和許可允許性方面都是免費的。

+0

感謝您的洞察力。 – 2010-12-23 17:30:31

+0

+1用於調用非託管代碼...通常只需使用基於控制檯的處理器。 – Tracker1 2012-02-09 22:06:45

+0

FreeImage怎麼樣? – jjxtra 2012-10-09 19:05:10

7

PNG一般是無損壓縮方案,這意味着圖像質量是永遠不會減少,除非你減少像素數(大小)或顏色深度。有三種方法可以減小PNG圖像的文件大小:

  • 減少像素數(通過縮小圖像);這裏有
  • 分辨率的明顯喪失使用不同的壓縮前的過濾器/ DEFLATE壓縮機參數(OptiPNG是我最喜歡的工具來自動選擇過濾器的最佳組合/壓縮設置)
  • 減少從真彩256色深(或更少)的顏色會給你大量的字節的儲蓄,但通常是在巨大的視覺成本(尤其是照片圖像)

好像.NET不具有一個內置的方式來改變預壓縮過濾器或壓縮機參數的PNG,所以你必須使用外部庫。 OptiPNG或任何other PNG優化工具不是本機.NET庫,因此您必須處理P /調用庫或運行單獨的進程來處理每個映像。但是,您通常會將儲蓄減少到5%或更少(儘管我已看到多達40%),因爲這最終是一個無損的過程。

我建議不要在您描述的自動化場景中減少顏色深度,因爲結果可能看起來真的很糟糕(想想老掉牙的GIF)。 (但是,如果您正在手動優化,請在Windows上查看Color Quantizer,在Mac上查看ImageAlpha)。沒有外部的依賴,並且被設計成是一種有損壓縮算法:

mainImg.Save(filePath, System.Drawing.Imaging.ImageFormat.Jpeg); // make sure you change `filePath` to end with jpg instead of png. 
+0

這不完全正確。 PNG實現了壓縮過濾器的概念,用於減少圖像大小而不會損失質量。它並不保證任何內容,但在某些情況下,這種改進可能非常重要。你可以在這裏閱讀:http://www.libpng.org/pub/png/pngintro.html – detunized 2010-12-11 19:26:27

+0

但我同意josh3736,最簡單也是最可靠的方法是使用JPEG。 – detunized 2010-12-11 19:28:36

+0

@detunized:是的,但壓縮過濾器可能不會實現有損壓縮,這是@Shawn真正要求的。無論如何,由他的用戶上傳的任何PNG必然已經應用了壓縮過濾器,所以不可能進一步減小文件大小。 – josh3736 2010-12-11 19:31:27

0

不幸的是.Net的png圖像處理器不會對輸出做任何優化啓發式處理。最好的辦法是在服務器上安裝一個optipng/pngcrush二進制文件,將調整後的輸出渲染爲一個臨時文件,然後通過System.Diagnostics.Process對其使用pngcrush。

大部分情況下,如果上傳的是照片,原始格式爲JPEG,那麼使用JPEG輸出可以更好地提供服務。