2009-04-07 156 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; 
    } 

欲了解更多信息,请参阅:

相关问题