繁体   English   中英

将8bpp索引位图转换为24bpp,然后使用相同的自定义调色板再次返回

[英]Converting 8bpp Indexed Bitmap to 24bpp and back again with the same custom color palette

我正在制作一个可以对某些位图进行图形编辑的工具。 我有一些带有现有调色板的8bppIndexed位图,必须将其转换为24bppRgb,以便我可以在其上绘画并根据用户选择的某些选项编辑像素的颜色。 位图图形是原始的8bpp .bmp文件:

//Get Bitmap from file
Bitmap graphic = new Bitmap(source);

//Get palette and pixel format
ColorPalette pal = graphic.Palette;
PixelFormat pix = graphic.PixelFormat; //Format8bppIndexed

//Create datagraphic in 24bppRgb to allow for editing
PixelFormat datapix = PixelFormat.Format24bppRgb;
Bitmap datagraphic = graphic.Clone(new Rectangle(0, 0, graphic.Width, graphic.Height), datapix);

在绘制和编辑Bitmap数据图形后,我试图将其转换回8bppIndexed,使用与Bitmap图形相同的调色板。 我可以这样:

//Convert back to graphic pixel format
datagraphic = datagraphic.Clone(new Rectangle(0, 0, datagraphic.Width, datagraphic.Height), pix); //Format8bppIndexed

//Apply color palette
datagraphic.Palette = pal;

但是,在克隆与图形具有相同像素格式的数据图形后,它将创建一个全新的调色板。 应用ColorPalette pal后,数据图形中的颜色全部不正确。 它们仅通过两个调色板之间的索引号匹配。 还有另一种方法可以保留颜色吗?

是的,位图需要使用自定义调色板进行8bppIndexed处理。 我试图避免需要通过Photoshop来使用正确的调色板更改所有最终结果数据图形的颜色索引。

我应该说我还是C#的新手。 我希望我清楚自己想做什么。 感谢您的帮助。 提前致谢。

将8位图像转换为24bpp很简单:您只需将其绘制在具有相同尺寸和首选像素格式的新图像上即可。

public static Bitmap PaintOn24bpp(Image image)
{
    Bitmap bp = new Bitmap(image.Width, image.Height, PixelFormat.Format24bppRgb);
    using (Graphics gr = Graphics.FromImage(bp))
        gr.DrawImage(image, new Rectangle(0, 0, bp.Width, bp.Height));
    return bp;
}

这适用于任何源图像,无论其像素格式如何,但是对于包含透明性的图像,您可能需要对其进行预处理以填充任何透明区域,因为我不知道考虑透明性的绘画是否可以用于您所使用的图像绘图不支持Alpha。

反之,将高彩色图像转换为索引图像,要复杂得多,但是如果您拥有调色板,那肯定是可能的。 在这种情况下,主要问题是使用Graphics不起作用,因为索引的图形没有彩色像素。 它们有一个调色板,而像素只是引用这些颜色。

编辑8位数据通常可以归结为建立一个包含图像数据的字节数组,然后将其转换为带有调色板的图像。 通过创建一个新的8bpp位图,使用LockBits函数打开其后备字节数组,然后使用Marshal.Copy将新数据复制到其中,来完成实际的转换。

之后,最后缺少的链接是一种将图像的彩色像素与最接近的调色板匹配相匹配的方法,因此,您可以将结果匹配的阵列作为一个8bpp图像进行烘烤。 通常,这是通过计算颜色到每种调色板颜色的勾股距离(在3D RGB颜色空间中),然后获取该距离最小的颜色的索引来完成的。

此答案详细说明了从头到尾的整个过程:

答:如何将彩色图像转换为只有两种预定义颜色的图像?

这处理2种颜色,但是处理2种或256种颜色的方法完全相同,因为两种情况下的最终结果都是8bpp图像。

可以对其进行优化,以直接处理24bpp图像,而不是将输入转换为32bpp,但这可能不值得付出努力,尤其是因为此处发布的方法几乎可以处理任何输入。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM