在 ImageSharp 中使用调色板/索引图像

Posted

技术标签:

【中文标题】在 ImageSharp 中使用调色板/索引图像【英文标题】:Working with palette / indexed images in ImageSharp 【发布时间】:2022-01-04 07:47:06 【问题描述】:

对于旧版游戏,我需要加载 BMP(或 PNG)调色板格式的图像并更改调色板上某些众所周知的索引(例如,使用绿色阴影替换使用索引 0-8 的红色渐变,以更改单位的颜色)。单独进行颜色替换是不够的,因为同一种颜色可能会被多个单元特征使用。

是否可以加载调色板图像并将颜色索引保留在 ImageSharp 中?当我使用Image.Load("FileName") 加载我的调色板单元图像时,它总是以 Argb32 模式加载,并且调色板丢失了。在 Photoshop 中,相同的图像在索引模式下正确加载。另外,我不确定可以使用哪些属性来查看/编辑调色板。

我没有在网上找到有关该主题的太多信息。我看到文档中有一个类型 IndexedImageFrame<TPixel>,但我不确定该类型是否/如何有助于解决上述问题。

编辑:正如 James South 正确指出的那样,ImageSharp 默认以 Rgba32 模式加载 PNG。

【问题讨论】:

那么...不要使用 ImageSharp,我猜?您可以使用System.Drawing 完美打开索引格式,使用LockBitsMarshal.Copy 获取原始底层字节。这就是我为my own classic game file formats conversion tool 所做的。 【参考方案1】:

当我使用 Image.Load("FileName") 加载调色板单元图像时,它总是以 Argb32 模式加载

实际上,如果加载 png,则为 Rgba32(尽管这可能会在未来发生变化)。为了保证像素格式,您应该使用通用变体。

在 Photoshop 中,相同的图像在索引模式下正确加载。

这不是 PhotoShop 正在做的事情。他们正在捕捉调色板并将其展示给您。任何像素格式的实际画布格式都是相同的。

ImageSharp 也是如此。解码后的图像是TPixel 的二维缓冲区,但我们在解码时捕获元数据并使用它来通知编码器以何种像素格式保存对图像进行编码。

也就是说...目前恐怕不支持在解码时捕获当前调色板。如果您想在GitHub repository 中提出问题,我们可能会在 V2 中考虑。

如果您有要捕获的信息然后调整/保存,则可以在图像编码期间使用带有更新调色板的 PaletteQuantizer。

【讨论】:

感谢@James South 的澄清!很高兴知道显式调色板写入基本上是可能的,但目前无法读取(至少没有通过 API 公开)。然而,简单地暴露它仍然无法实现上述目标,因为调色板索引和像素之间的连接无论如何都会丢失。这将需要基于调色板的画布/像素格式。我知道 Photoshop 也不这样做。 很少有系统仍然正确支持索引格式......这真的是一种耻辱。 ImageSharp 在索引格式上工作得非常好。 @JamesSouth 我更多地指的是图像编辑器。 Gimp 在技术上支持它,但它像糖蜜一样缓慢。

以上是关于在 ImageSharp 中使用调色板/索引图像的主要内容,如果未能解决你的问题,请参考以下文章

Gatsby - 从 csv 文件中的参考字段制作流体图像宽度 ImageSharp

text 使用ImageSharp调整ASP.NET Core中的图像大小

ImageSharp一个专注于NetCore平台图像处理的开源项目

ImageSharp一个专注于NetCore平台图像处理的开源项目

BMP文件中图像数据是按啥顺序存放的?

带有 AzureBlobStorageImageProvider 的 ImageSharp.Web 提供 404