2009-04-07 125 views
2

我有一個圖像,我在內存中創建爲Format24bppRgb。將內存中的24位圖像轉換爲索引顏色

我把它保存爲一個PNG,它是24kb。

如果我用photoshop保存與24位PNG相同的圖像,它會變成大約相同的尺寸,但如果我將它保存爲只有32種顏色的8位PNG,則會降低到5kb。

如何使用C#/ GDI +/System.Drawing創建PNG文件的索引版本?

我很難找到這個問題的任何答案,不只適用於灰度圖像或需要外部庫。在GDI +中是不可能的?

回答

0

您試圖將16777216種顏色轉換爲32.這是一個不平凡的問題,並且有很多方法可以做到這一點,所有這些方法都有其優點和缺點。這不是你經常需要做的事情,特別是全綵色顯示器無處不在。

此Microsoft文章包含有關應該與PNG相關的GIF文件的一些信息。

http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q319061

+0

但Photoshop中使得它看起來那麼容易了:-)我期待在FreeImage.NET現在 – 2009-04-08 21:56:51

+1

或者無論如何,圖像可能有32種顏色,在這種情況下,您不會丟失任何東西。 – axk 2011-10-25 11:33:03

2

我結束了使用FreeImageAPI DLL,用C#包裝。我儘量避免使用第三方庫,但我認爲沒有其他選擇。它似乎是一個非常標準和使用良好的庫。

在我的情況下,我有一個System.Drawing.Image對象'image'這是動態創建的 - 我想保存到HttpContext輸出流作爲壓縮圖像。請注意,Image沒有所需的GetHbitmap()方法,但是Bitmap確實如此。

// convert image to a 'FreeImageAPI' image 
var fiBitmap = FreeImageAPI.FreeImageBitmap.FromHbitmap((image as Bitmap).GetHbitmap()); 
fiBitmap.ConvertColorDepth(FreeImageAPI.FREE_IMAGE_COLOR_DEPTH.FICD_08_BPP); 

// see http://stackoverflow.com/questions/582766 
MemoryStream ms = new MemoryStream(); 
fiBitmap.Save(ms, FreeImageAPI.FREE_IMAGE_FORMAT.FIF_PNG, FreeImageAPI.FREE_IMAGE_SAVE_FLAGS.PNG_Z_BEST_COMPRESSION); 
context.HttpContext.Response.OutputStream.Write(ms.ToArray(), 0, (int)ms.Length); 

我的24KB的位圖現在只有9KB :-)

提示:一定要兼得 'FreeImageNET' 並在你的bin可用 '的FreeImage' 的DLL,當你運行它。目前,C#示例項目包含對「Library.DLL」的引用,該引用似乎不存在於其zip文件中。儘管使用FreeImageNET.dllFreeImage.dll。如果你沒有意識到,你會得到一個惱人的文件沒有找到錯誤FreeImageNet!= FreeImage

+0

如何在Windows 7 64位上安裝它? – 2013-02-10 22:12:08

1

您可以使用nQuant(您可以使用nuget安裝,或參閱下面的參考資料)進行此操作。以下示例轉換磁盤上的映像,並且可以隨時調整以滿足您的需求。

public static bool TryNQuantify(string inputFilename, string outputFilename) 
    { 
     var quantizer = new nQuant.WuQuantizer(); 
     var bitmap = new Bitmap(inputFilename); 
     if (bitmap.PixelFormat != System.Drawing.Imaging.PixelFormat.Format32bppArgb) 
     { 
      ConvertTo32bppAndDisposeOriginal(ref bitmap); 
     } 

     try 
     { 
      using (var quantized = quantizer.QuantizeImage(bitmap)) 
      { 
       quantized.Save(outputFilename, System.Drawing.Imaging.ImageFormat.Png); 
      } 
     } 
     catch 
     { 
      return false; 
     } 
     finally 
     { 
      bitmap.Dispose(); 
     } 
     return true; 
    } 

    private static void ConvertTo32bppAndDisposeOriginal(ref Bitmap img) 
    { 
     var bmp = new Bitmap(img.Width, img.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb); 
     using (var gr = Graphics.FromImage(bmp)) 
      gr.DrawImage(img, new Rectangle(0, 0, img.Width, img.Height)); 
     img.Dispose(); 
     img = bmp; 
    } 

欲瞭解更多信息,請參閱:

相關問題