使用NQUANT量化图像时的误差 - c#

我最近获得了NuGet软件包Nquant。

我计划使用它来减小位图的文件大小并将其保存到PNG中。但是我得到这个错误:

您尝试量化的图像不包含32位ARGB调色板。该图像的位深度为8,具有256种颜色。

这里有人使用过Nquant吗?您是否遇到了此错误,以及如何解决?

我的代码供您参考:

var bitmap = new Bitmap(width, jbgsize / height, PixelFormat.Format8bppIndexed);
        ColorPalette pal = bitmap.Palette;
        for (int i = 0; i <= 255; i++)
        {
            // create greyscale color table
            pal.Entries[i] = Color.FromArgb(i, i, i);
        }
        bitmap.Palette = pal; // you need to re-set this property to force the new ColorPalette

        var bitmap_data = bitmap.LockBits(new Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);
        Marshal.Copy(output, 0, bitmap_data.Scan0, output.Length);
        bitmap.UnlockBits(bitmap_data);
        MemoryStream stream = new MemoryStream();
var quantizer = new WuQuantizer();
        using(var bmp = new Bitmap(bitmap))
        {
            using (var quantized = quantizer.QuantizeImage(bitmap))
            {
                quantized.Save(stream, ImageFormat.Png);
            }
        }

        byteArray = stream.ToArray();
        return byteArray.Concat(output).ToArray();

参考方案

您可以将图像转换为Format32bppPArgb,然后对其进行量化。

这是我缩小图像大小约3倍的工作示例。

public static byte[] CompressImageStream(byte[] imageStream)
{
    using (var ms = new MemoryStream(imageStream))
    using (var original = new Bitmap(ms))
    using (var clonedWith32PixelsFormat = new Bitmap(
        original.Width,
        original.Height,
        PixelFormat.Format32bppPArgb))
    {
        using (Graphics gr = Graphics.FromImage(clonedWith32PixelsFormat))
        {
            gr.DrawImage(
                original,
                new Rectangle(0, 0, clonedWith32PixelsFormat.Width, clonedWith32PixelsFormat.Height));
        }

        using (Image compressedImage = new WuQuantizer().QuantizeImage(clonedWith32PixelsFormat))
        {
            return ImageToByteArray(compressedImage);
        }
    }
}

public static byte[] ImageToByteArray(Image image)
{
    if (image == null)
    {
        throw new ArgumentNullException(nameof(image));
    }

    using (var stream = new MemoryStream())
    {
        image.Save(stream, ImageFormat.Png);
        return stream.ToArray();
    }
}

LeetCode题解水壶问题

给你一个装满水的 8 升满壶和两个分别是 5 升、3 升的空壶,请想个优雅的办法,使得其中一个水壶恰好装 4 升水,每一步的操作只能是倒空或倒满。题解:``` .js/** * 思路: * 每个容器有两个选择,比如:A,可以倒入B,或者倒入C * 同样,B可以倒入A,也可以倒入C * 那么每次就有8种可能 * * 每产生一种可能,顺着这种可能的结果,继续去遍…

生成带有透明部分的图像 - c#

我试图生成一个小正方形32 x 32像素,中间有一个10 x 10正方形的透明间隙。这是我到目前为止的内容:private Image CreatePicture(){ // Create a new Bitmap object, 32 x 32 pixels in size Bitmap canvas = new Bitmap(32,32,System.D…

LeetCode题解计算机为什么是基于二进制的?

可以是三进制么?二进制有什么好处?题解:为什么叫电子计算机?算盘应该没有二进制

LeetCode题解统计城市的所有灯泡

这个是我刚毕业的时候,一个真实的面试题,这是一个开放题。题目描述:想办法,将一个城市的所有灯泡数量统计出来。题解:费米估算法1、如果某个城市常驻人口有1000万2、假设每5人居住在一套房里,每套房有灯泡5只,那么住宅灯泡共有1000万只3、假设公众场所每10人共享一只灯泡,那么共有100万只4、主要的这两者相加就得出了1100万只当然实际上这是估算的,具体应…

LeetCode题解黑白圆盘

一个圆盘被涂上了黑白二色,两种颜色各占一个半圆。圆盘以一个未知的速度、按一个未知的方向旋转。你有一种特殊的相机可以让你即时观察到圆上的一个点的颜色。你需要多少个相机才能确定圆盘旋转的方向?题解:可以用一个相机即可