.net 将24位内存图像转换为索引颜色
我在内存中创建了一个映像,格式为24bpprgb 我将其保存为PNG,大小为24kb 如果我用photoshop将同一图像保存为24位PNG,大小大致相同,但如果我将其保存为8位PNG,仅使用32种颜色,大小将降至5kb 如何使用C#/GDI+/System.Drawing创建PNG文件的索引版本.net 将24位内存图像转换为索引颜色,.net,gdi+,system.drawing,.net,Gdi+,System.drawing,我在内存中创建了一个映像,格式为24bpprgb 我将其保存为PNG,大小为24kb 如果我用photoshop将同一图像保存为24位PNG,大小大致相同,但如果我将其保存为8位PNG,仅使用32种颜色,大小将降至5kb 如何使用C#/GDI+/System.Drawing创建PNG文件的索引版本 我很难找到这个问题的答案,这些答案不仅仅适用于灰度图像或需要外部库。这在GDI+中是不可能的吗?您正在尝试将16777216种颜色转换为32种。这是一个非常重要的问题,有很多方法可以解决,所有这些方法
我很难找到这个问题的答案,这些答案不仅仅适用于灰度图像或需要外部库。这在GDI+中是不可能的吗?您正在尝试将16777216种颜色转换为32种。这是一个非常重要的问题,有很多方法可以解决,所有这些方法都有其优缺点。这不是你经常需要做的事情,尤其是在全彩色显示器变得无处不在的情况下 这篇Microsoft文章提供了一些关于GIF文件的信息,这些文件也应该与PNG相关 我最终使用了带有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”和“FreeImage”DLL都在您的存储箱中可用。目前,C#示例项目包含对“Library.DLL”的引用,而该引用似乎不存在于其zip文件中。不过,使用
freeimagnet.dll
和FreeImage.dll
仍然有效。如果您没有意识到,FreeImageNet
!=<代码>免费图像 您可以使用nQuent(您可以使用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;
}
有关更多信息,请参阅: