gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-11-30 13:05:30 27 4
gpt4 key购买 nike

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

由于 Graphics 不支持索引颜色,因此您不能使用它,因此我尝试构建一个非索引位图(使用 Graphics)并将其转换为索引颜色位图。转换很好,但我不知道如何设置输出图像的调色板。它默认为一些预定义的调色板,这与我要查找的内容几乎没有关系。

所以:

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

回复:WriteableBitmap:我似乎无法在网上找到任何关于如何在这种情况下组合 PNG 的示例,或者即使尝试这样做是否有意义。

最佳答案

事实证明,我能够构建一个非索引位图并像这样使用 PngBitmapEncoder 进行转换:

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

加上辅助扩展方法:

    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 位的。到目前为止看起来像是一个功能……不过如果我能明确控制它就好了。

关于c# - 在 .NET 中组合多个 PNG8 图像的最简单方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4356973/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com