我有一个 PNG 图像处理工作流程,该工作流程依赖于 24 位真彩色格式(也称为 RGB 图像)的图像。 PNG 允许 RGB 或索引颜色表示。
NetPBM 的程序pnmtopng
根据图像中不同颜色的数量自动决定写入哪种类型的图像。我记得在某处读过,如果这个数字是 256 或更少,它会自动写入索引图像。
有没有办法保留图像的类型?
例如,如果我使用 NetPBM 翻转图像,如下所示
pngtopnm true-color-image.png | pamflip -tb | pnmtopng > new-image.png
有没有办法确保新图像也是真彩色图像?
目前我可以检查该图像的类型是错误的,因为它的大小比原始图像小大约 50%。
37155 true-color-image.png
27463 new-image.png
我希望新图像的大小与原始图像的大小大致相同。
identify
ImageMagick还给出了这两个图像的以下信息:
true-color-image.png PNG 300x280 300x280+0+0 8-bit sRGB 37155B
new-image.png PNG 300x280 300x280+0+0 8-bit sRGB 61c 27463B
答案1
我找到了解决方案PNG:权威指南(第 5 章)作者:格雷格·罗洛夫斯。
上面写着:
细心的读者会记得,GIF 图像始终是基于调色板的,但在描述 NetPBM 格式时我并没有提及任何有关调色板的内容。事实上,NetPBM 没有调色板的概念; giftopnm 通常将 GIF 图像转换为 PPM 格式(RGB 风格)。幸运的是,pnmtopng 足够智能,可以对图像中的颜色进行计数,并在颜色数量为 256 种或更少时自动写入基于调色板的 PNG 图像。它同样会检测彩色图像是否实际上仅由灰度值组成;在这种情况下,它将写入灰度 PNG 或基于调色板的 PNG,具体取决于可以用最少的位写入哪一种。然而,这种自动检查是有代价的:因为它需要检查每个像素,所以对于大图像来说可能会非常慢。因此 pnmtopng 包括一个-力量跳过检查的选项。
所以,虽然引入期权的主要目的-force
是为了加速转换。就我而言,它有助于确保兼容性。
pngtopnm true-color-image.png | pamflip -tb | pnmtopng > flipped-indexed.png
pngtopnm true-color-image.png | pamflip -tb | pnmtopng -force > flipped-truecolor.png
运行identify
确认该选项按预期工作。
flipped-indexed.png PNG 300x280 300x280+0+0 8-bit sRGB 61c 27463B 0.000u 0:00.000
flipped-truecolor.png PNG 300x280 300x280+0+0 8-bit sRGB 37038B 0.000u 0:00.000
为了完整起见,这里有一个完整的示例。
# 1. Generate a green/blue two color image
ppmrough -left 30 -right 30 -top 30 -bottom 30 -width 300 -height 280 \
-var 5 -bg green -fg blue > twocolor.ppm
# 2. Convert to PNG
pnmtopng twocolor.ppm > twocolor-indexed.png
# 3. Convert to PNG forcing Truecolor output
pnmtopng -force twocolor.ppm > twocolor-truecolor.png
# 4. Checking the results
identify twocolor-indexed.png twocolor-truecolor.png
这将生成两个 PNG 图像。一个是 2 色索引调色板,另一个是 Truecolor PNG。
twocolor-indexed.png PNG 300x280 300x280+0+0 8-bit sRGB 2c 1018B 0.000u 0:00.000
twocolor-truecolor.png PNG 300x280 300x280+0+0 8-bit sRGB 2421B 0.000u 0:00.000
答案2
这对我来说就像是一个 XY 问题。
png 是一种压缩图像格式,旨在以尽可能最小的方式存储图像,而不减少或改变信息内容。如果图像具有 256 种或更少颜色,则可以将其存储为索引,而不会丢失任何 RGB 数据。
如果您的应用程序使用合适的库来读取图像,则它不应该关心它是索引格式还是真彩色格式。无论哪种方式,它都应该获得图像中像素的相同原始数据。如果您手工编写的 png 解码器无法处理索引图像,那么切换到库可能是个好主意。
如果您确实想要未索引的原始 RGB 图像,则应将其转换为 ppm 而不是 png。