我有一个图像,我在内存中创建为Format24bppRgb。将内存中的24位图像转换为索引颜色
我把它保存为一个PNG,它是24kb。
如果我用photoshop保存与24位PNG相同的图像,它会变成大约相同的尺寸,但如果我将它保存为只有32种颜色的8位PNG,则会降低到5kb。
如何使用C#/ GDI +/System.Drawing创建PNG文件的索引版本?
我很难找到这个问题的任何答案,不只适用于灰度图像或需要外部库。在GDI +中是不可能的?
我有一个图像,我在内存中创建为Format24bppRgb。将内存中的24位图像转换为索引颜色
我把它保存为一个PNG,它是24kb。
如果我用photoshop保存与24位PNG相同的图像,它会变成大约相同的尺寸,但如果我将它保存为只有32种颜色的8位PNG,则会降低到5kb。
如何使用C#/ GDI +/System.Drawing创建PNG文件的索引版本?
我很难找到这个问题的任何答案,不只适用于灰度图像或需要外部库。在GDI +中是不可能的?
您试图将16777216种颜色转换为32.这是一个不平凡的问题,并且有很多方法可以做到这一点,所有这些方法都有其优点和缺点。这不是你经常需要做的事情,特别是全彩色显示器无处不在。
此Microsoft文章包含有关应该与PNG相关的GIF文件的一些信息。
http://support.microsoft.com/default.aspx?scid=kb;EN-US;Q319061
我结束了使用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.dll
和FreeImage.dll
。如果你没有意识到,你会得到一个恼人的文件没有找到错误FreeImageNet
!= FreeImage
!
如何在Windows 7 64位上安装它? – 2013-02-10 22:12:08
您可以使用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;
}
欲了解更多信息,请参阅:
但Photoshop中使得它看起来那么容易了:-)我期待在FreeImage.NET现在 – 2009-04-08 21:56:51
或者无论如何,图像可能有32种颜色,在这种情况下,您不会丢失任何东西。 – axk 2011-10-25 11:33:03