Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/24.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 将24位内存图像转换为索引颜色_.net_Gdi+_System.drawing - Fatal编程技术网

.net 将24位内存图像转换为索引颜色

.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种。这是一个非常重要的问题,有很多方法可以解决,所有这些方法

我在内存中创建了一个映像,格式为24bpprgb

我将其保存为PNG,大小为24kb

如果我用photoshop将同一图像保存为24位PNG,大小大致相同,但如果我将其保存为8位PNG,仅使用32种颜色,大小将降至5kb

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


我很难找到这个问题的答案,这些答案不仅仅适用于灰度图像或需要外部库。这在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;
    }
有关更多信息,请参阅:


但是Photoshop让它看起来很简单:-)我现在正在查看FreeImage.NET,或者该图像可能有32种颜色,在这种情况下,您不会丢失任何内容。如何在windows 7 64位上安装它?请小心使用bitmap.GetHbitmap()。你必须手动释放内存,否则它会泄漏。1.[DllImport(“gdi32.dll”)]私有静态外部bool DeleteObject(IntPtr hObject);2.IntPtr hBitmap=bitmap.GetHbitmap();3.FreeImageBitmap FreeImageBitmap=FreeImageBitmap.FromHbitmap(hBitmap);4.(做事)5。删除对象(hBitmap);如果您想要不是1位通道的alpha通道,这很好。你会得到一个8位的alpha图像,类似于tinypng.com给你的。但请注意,这是相当缓慢的工作对我来说很好,但重要的是要注意,当我处理高度大于4550像素的图像时,它无法生成图像,输出是一个空的灰色图像。