在.NET组合几个PNG8图像最简单的方法 [英] Easiest way to combine several PNG8 images in .NET

查看:307
本文介绍了在.NET组合几个PNG8图像最简单的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想了一堆8位PNG图像合并成一个更大的PNG图像在C#。奇怪的是,这似乎是特别困难的。

I'm trying to combine a bunch of 8-bit PNG images into a larger PNG image in C#. Oddly enough, this seems to be particularly difficult.

由于显卡不支持索引颜色,你不能使用,所以我试图建立一个非索引位图(使用图形界面)和转换,为索引颜色的位图。转换是好的,但我想不出如何设置输出图像的调色板。它默认为一些pre定义的调色板里面有什么与我在寻找什么。

Since Graphics does not support indexed color, you can't use that, so I tried building a non-indexed Bitmap (using Graphics) and converting that to indexed color bitmap. The conversion is fine, but I can't figure out how to set the palette of the output image. It defaults to some pre-defined palette which has little to do with what I'm looking for.

所以:

有没有办法来控制位图调色板?还是有另一种方法(System.Windows.Media.Imaging.WriteableBitmap例如),它可以支持呢?

Is there a way to control the bitmap palette? Or is there another method (System.Windows.Media.Imaging.WriteableBitmap, for example) which can support this?

回复:WriteableBitmap的。我似乎无法找到任何的例子网上怎么一会去在这方面相结合的PNG图像,或者即使它使任何意义,尝试它

Re: WriteableBitmap: I can't seem to find any examples online of how one would go about combining PNGs in this context, or even if it makes any sense to attempt it.

推荐答案

事实证明,我能够打造出一个非索引位图和转换使用PngBitmapEn codeR像这样:

It turns out that I was able to build out a non-indexed bitmap and convert using PngBitmapEncoder like so:

    byte[] ConvertTo8bpp(Bitmap sourceBitmap)
    {
        // generate a custom palette for the bitmap (I already had a list of colors
        // from a previous operation
        Dictionary<System.Drawing.Color, byte> colorDict = new Dictionary<System.Drawing.Color, byte>(); // lookup table for conversion to indexed color
        List<System.Windows.Media.Color> colorList = new List<System.Windows.Media.Color>(); // list for palette creation
        byte index = 0;
        unchecked
        {
            foreach (var cc in ColorsFromPreviousOperation)
            {
                colorDict[cc] = index++;
                colorList.Add(cc.ToMediaColor());
            }
        }
        System.Windows.Media.Imaging.BitmapPalette bmpPal = new System.Windows.Media.Imaging.BitmapPalette(colorList);

        // create the byte array of raw image data
        int width = sourceBitmap.Width;
        int height = sourceBitmap.Height;
        int stride = sourceBitmap.Width;
        byte[] imageData = new byte[width * height];

        for (int x = 0; x < width; ++x)
            for (int y = 0; y < height; ++y)
            {
                var pixelColor = sourceBitmap.GetPixel(x, y);
                imageData[x + (stride * y)] = colorDict[pixelColor];
            }

        // generate the image source
        var bsource = BitmapSource.Create(width, height, 96, 96, PixelFormats.Indexed8, bmpPal, imageData, stride);

        // encode the image
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Interlace = PngInterlaceOption.Off;
        encoder.Frames.Add(BitmapFrame.Create(bsource));

        MemoryStream outputStream = new MemoryStream();
        encoder.Save(outputStream);

        return outputStream.ToArray();
    }

加辅助扩展方法:

Plus the helper extension method:

    public static System.Windows.Media.Color ToMediaColor(this System.Drawing.Color color)
    {
        return new System.Windows.Media.Color()
        {
            A = color.A,
            R = color.R,
            G = color.G,
            B = color.B
        };
    }

请注意的警惕:在PngBitmapEn codeR实际上似乎减少8 BPP计数到4时,就可以了。当我测试用6种颜色,例如,输出PNG是只有4位。当我使用一个更多彩丰富的图像,这是8位。看起来像一个功能,那么远,虽然这将是很好,如果我有明确的控制权。

Note for the wary: the PngBitmapEncoder actually seems to reduce the bpp count from 8 to 4 when it can. When I test with 6 colors, for example, the output PNG is only 4-bit. When I use a more color-rich image, it's 8-bit. Looks like a feature so far... though it would be nice if I had explicit control over it.

这篇关于在.NET组合几个PNG8图像最简单的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆