我最近更新到 IM 6.9.9-3,发现一些非常不一致的行为。这是两张看似相似的图片:
图片1.png
图片2.png
让我们看看 IM 对他们的色彩空间的看法:
[grochmal@phoenix]$ identify *
image1.png PNG 95x74 95x74+0+0 8-bit sRGB 1230B 0.000u 0:00.000
image2.png PNG 69x102 69x102+0+0 8-bit sRGB 2040B 0.000u 0:00.000
[grochmal@phoenix]$ identify -verbose image1.png | grep -A 2 Color
Colorspace: sRGB
Depth: 8-bit
Channel depth:
--
Colors: 96
Histogram:
1357: (217,217,217,255) #D9D9D9FF grey85
[grochmal@phoenix]$ identify -verbose image2.png | grep -A 2 Color
Colorspace: sRGB
Depth: 8-bit
Channel depth:
--
Colors: 188
Histogram:
1: ( 26, 26, 26,255) #1A1A1AFF graya(26,1)
两者的颜色都少于 255 种(灰度所需),所以让我们尝试将convert
它们转换为 JPEG:
[grochmal@phoenix]$ convert image1.png -strip -quality 80 image1.jpg
[grochmal@phoenix]$ convert image2.png -strip -quality 80 image2.jpg
很好,没有错误。但现在其中一张图像是灰度图像,另一张图像是 sRGB 图像,此外,IM 还为其中一张图像添加了色彩图:
[grochmal@phoenix]$ identify -verbose image1.jpg | grep -A 2 Color
Colorspace: sRGB
Depth: 8-bit
Channel depth:
--
Colors: 37
Histogram:
1520: (217,217,217) #D9D9D9 gray(217)
[grochmal@phoenix]$ identify -verbose image2.jpg | grep -A 2 Color
Colorspace: Gray
Depth: 8-bit
Channel depth:
--
Colors: 195
Histogram:
1: ( 14, 14, 14) #0E0E0E gray(14)
--
Colormap entries: 256
Colormap:
0: ( 0, 0, 0) #000000 gray(0)
1: ( 1, 1, 1) #010101 gray(1)
[grochmal@phoenix]$ identify *
image1.jpg JPEG 95x74 95x74+0+0 8-bit sRGB 397B 0.000u 0:00.000
image1.png PNG 95x74 95x74+0+0 8-bit sRGB 1230B 0.000u 0:00.000
image2.jpg JPEG 69x102 69x102+0+0 8-bit Gray 256c 687B 0.000u 0:00.000
image2.png PNG 69x102 69x102+0+0 8-bit sRGB 2040B 0.000u 0:00.000
颜色图现在破坏了我的一些缩略图制作脚本(我使用的大多数图像实际上要大得多,但这两个是我实验最多的图像;这是一个网页游戏)。然而,这提出了三个问题:
IM 如何执行以下决策:(1) 在转换期间更改图像的色彩空间以及 (2) 添加色彩图的决策?
如何强制 IM 执行更一致的行为(最好不要向任何内容添加颜色图)?
我可以强制删除颜色图吗? (我试了5个小时没有成功。)
答案1
感谢@WumpusQ.Wumbley 为我指明了正确的方向。
长话短说:用于-type TrueColor
从 PseudoClass 图像的调色板类型中删除颜色图。
颜色图不是 PseudoClass
阅读 IM 论坛后,我终于(或多或少)了解了什么是图像中的色彩图以及如何处理它。首先,两者之间有一个区别直接类和伪类:
- A直接类存储每个像素的颜色值。
- A伪类使用颜色表,然后将偏移量存储到该表中。
这就是我困惑的根源:PseudoClass 不是颜色图,它们是不同的东西。由于 IM 几乎总是将 PseudoClass 图像转换为 DirectClass 图像,因此我感到困惑。
涉及图像修改的主要操作通常会在应用操作之前将 PsuedoColor 图像(使用颜色表的图像)升级为 DirectColor(每个像素使用单独的颜色值的图像)。
来源 (PS DirectClass 和 PseudoClass 是 DirectColor 和 PseudoColor 的同义词)
那么,什么是色图?
这色彩图是存储在图像中的调色板的颜色索引。这是非常类似于伪类因为它也是一个颜色表,所以区别在于伪类将仅包括图像中存在的颜色和色彩图将包含调色板中的所有颜色。请注意,一个伪类将有一个色彩图部分,但这将是颜色表伪类不是一个调色板类型(是的,这在 IM 方面非常令人困惑)。
这色彩图-type
由IM 选项定义:
-type type
the image type.
Choose from: Bilevel, Grayscale, GrayscaleMatte,
Palette, PaletteMatte, TrueColor, TrueColorMatte,
ColorSeparation, or ColorSeparationMatte.
Normally, when a format supports different subformats such
as grayscale and truecolor, the encoder will try to choose an
efficient subformat. The -type option can be used to override
this behavior. For example, to prevent a JPEG from being written
in grayscale format even though only gray pixels are present, use.
convert bird.png -type TrueColor bird.jpg
Similarly, use -type TrueColorMatte to force the encoder to write
an alpha channel even though the image is opaque, if the output
format supports transparency.
Use -type optimize to ensure the image is written in the
smallest possible file size.
请注意,类型不同于色彩空间。大多数图像都会有类似的类型一个色彩空间,例如Type: Grayscale
和Colorspace: Gray
,但情况不一定如此。上传到我的服务器的图像(在问题中)有一个明显的类型和色彩空间。
这类型从上面的人可以理解为:
- 双层:黑白(我认为没有人还在使用这个)
- 灰度:0-255 是灰色阴影
- 调色板:使用图像中存在的色彩图
- 本色:使用标准配色方案之一(目前最有可能是 sRGB)
- 分色:不确定,但我认为它单独存储频道
- |以上之一|哑光:强制存在 Alpha 通道。
注意:按照今天的标准,在中写入灰度图像之间的区别sRGB色彩空间或在灰色的色彩空间几乎可以忽略不计。 (使用纯 RGB 代替 sRGB 的效果也可以忽略不计,并且图像通常会显示得很差。不要使用纯 RGB,而使用 sRGB。)
返回图像
现在我们可以解释 IM 做出的决定,我们可以说它是图片1.png这是有问题的,而不是 IM。让我们再次看一下图像:
[grochmal@phoenix so]$ identify -verbose image1.png | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 95x74+0+0
Resolution: 28.35x28.35
Print size: 3.35097x2.61023
--
Type: PaletteAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
red: 8-bit
--
Colors: 96
Histogram:
1357: (217,217,217,255) #D9D9D9FF grey85
16: (217,217,218,255) #D9D9DAFF srgba(217,217,218,1)
[grochmal@phoenix so]$ identify -verbose image2.png | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 69x102+0+0
Resolution: 28.35x28.35
Print size: 2.43386x3.59788
--
Type: GrayscaleAlpha
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
gray: 8-bit
--
Colors: 188
Histogram:
1: ( 26, 26, 26,255) #1A1A1AFF graya(26,1)
1: ( 35, 35, 35,255) #232323FF graya(35,1)
我们可以看到图片1.png有一个PaletteAlpha
类型(或者PaletteMatte
用 IM 术语来说)并且图片2有一个GrayscaleAlpha
类型。
事实是图片1.png没有色彩图完全错误。因此,有缺陷的图像作者一定将该图像写为具有色彩图但不写色彩图到图像中。
当 IM 发现图像应该有色彩图它可能根据猜测分配一个。猜测似乎是灰度在转换过程中添加的颜色图。
(请参阅问题以查看猜测转换的图像的输出)
如何修复它?
幸运的是,我们可以通过告诉 IM 我们不想保留或猜测来帮助 IM类型的图像。我们只是想要一个使用标准颜色图(出于我们的目的,sRGB 或灰色)中的颜色的图像,而不是我们无论如何都没有的调色板(因为有问题的图像编写器没有将其写入图像中)。
我们用-type TrueColor
:
[grochmal@phoenix so]$ convert image1.png -strip -quality 80 -type TrueColor image1.jpg
[grochmal@phoenix so]$ convert image2.png -strip -quality 80 -type TrueColor image2.jpg
图像按照我们预期的方式显示:
[grochmal@phoenix so]$ identify -verbose image1.jpg | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 95x74+0+0
Resolution: 28x28
Print size: 3.39286x2.64286
--
Type: Grayscale
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
gray: 8-bit
--
Colors: 37
Histogram:
1520: (217,217,217) #D9D9D9 gray(217)
95: (219,219,219) #DBDBDB gray(219)
[grochmal@phoenix so]$ identify -verbose image2.jpg | grep -A 3 -e 'Color\|Type\|Class'
Class: DirectClass
Geometry: 69x102+0+0
Resolution: 28x28
Print size: 2.46429x3.64286
--
Type: Grayscale
Endianess: Undefined
Colorspace: sRGB
Depth: 8-bit
Channel depth:
gray: 8-bit
--
Colors: 195
Histogram:
1: ( 14, 14, 14) #0E0E0E gray(14)
1: ( 37, 37, 37) #252525 gray(37)
请注意,IM 发现图像使用像素灰度并给出了DirectClass、灰度、sRGB图像,这可能是我们在几乎所有情况下所追求的。
如果您改为使用,-type Grayscale
您将得到伪类、格雷斯克莱、格雷图像,这可能会为您节省一些字节(对于 100-500k 的典型 Web 图像,可能会节省 10-20k),但代价是格式兼容性较差。例如,我pygtk
有时会呕吐伪类图像,我猜缺乏向后兼容性。