在.NET中组合多个PNG8图像的最简单方法

我试图将一堆8位PNG图像组合成一个C#中较大的PNG图像。 奇怪的是,这似乎特别困难。

由于Graphics不支持索引颜色,你不能使用它,所以我尝试构建一个非索引的Bitmap(使用Graphics)并将其转换为索引颜色位图。 转换很好,但我无法弄清楚如何设置输出图像的调色板。 它默认为一些预定义的调色板,与我正在寻找的内容几乎没有关系。

所以:

有没有办法控制位图调色板? 或者是否有另一种方法(例如System.Windows.Media.Imaging.WriteableBitmap)可以支持这个?

Re:WriteableBitmap:我似乎无法在网上找到任何关于如何在这种情况下组合PNG的例子,或者即使尝试它也没有任何意义。

免责声明,我在Atalasoft工作。

我们的产品DotImage Photo是免费的,可以做到这一点。

阅读PNG

AtalaImage img = new AtalaImage("image.png"); 

要转换为24 bpp

  img = img.GetChangedPixelFormat(newPixelFormat); 

创建所需大小的图像

  AtalaImage img2 = new AtalaImage(width, height, color); 

使用OverlayCommand将img叠加到img2上

  OverlayCommand cmd = new OverlayCommand(img); cmd.Apply(img2, point); 

要保存

  img2.Save("new.png", new PngEncoder(), null); 

如果您需要帮助,请对此答案发表评论或进行论坛参赛。

事实certificate,我能够构建一个非索引位图并使用PngBitmapEncoder进行转换,如下所示:

  byte[] ConvertTo8bpp(Bitmap sourceBitmap) { // generate a custom palette for the bitmap (I already had a list of colors // from a previous operation Dictionary colorDict = new Dictionary(); // lookup table for conversion to indexed color List colorList = new List(); // 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(); } 

加上帮助扩展方法:

  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 }; } 

注意警惕:PngBitmapEncoder实际上似乎可以将bpp计数从8减少到4。 例如,当我使用6种颜色进行测试时,输出PNG仅为4位。 当我使用颜色更丰富的图像时,它是8位的。 到目前为止看起来像一个function......虽然如果我对它有明确的控制会很好。