ImageMagic 如何決定顏色貼圖?
我最近更新到 IM 6.9.9-3 並發現了一些非常不一致的行為。這是兩張看似相似的圖片:
image1.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 個小時沒有成功。)
感謝@WumpusQ.Wumbley 為我指明了正確的方向。
**TL;DR:**用於
-type TrueColor
從 PseudoClass 圖像的調色板類型中刪除顏色圖。顏色圖不是 PseudoClass
閱讀 IM 論壇後,我終於(或多或少)了解了什麼是圖像中的顏色圖以及如何處理它。首先DirectClass和PseudoClass之間有區別:
- DirectClass儲存每個像素的顏色值。
- PseudoClass使用顏色表,然後將偏移量儲存到該表中**。**
這是我困惑的根源:PseudoClass 不是 colourmap,它們是不同的東西。而且由於 IM 幾乎總是將 PseudoClass 圖像轉換為 DirectClass 圖像,我感到很困惑。
涉及圖像修改的主要操作通常會在應用操作之前將 PsuedoColor 圖像(使用顏色表的圖像)升級為 DirectColor(對每個像素使用單獨顏色值的圖像)。
源 (PS DirectClass 和 PseudoClass 是 DirectColor 和 PseudoColor 的同義詞)
那麼,什麼是色圖?
顏色圖是針對儲存在圖像中的調色板的顏色索引。這與PseudoClass非常相似,因為它也是一個顏色表,不同之處在於PseudoClass將僅包括圖像中存在的顏色,而顏色圖將包括調色板中的所有顏色。請注意,PseudoClass將有一個顏色圖部分,但這將是 PseudoClass 的顏色表,而不是Palette類型(是的,這在 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與colourspace不同。大多數圖像將具有類似的顏色空間**類型,例如和,但不一定是這種情況。上傳到我的伺服器的圖像(在問題中)具有不同的type和colourspace。
Type: Grayscale``Colorspace: Gray
上面 man的類型可以理解為:
- Bilevel:黑白(我認為沒有人仍然使用它)
- 灰度:0-255 是灰度的陰影
- 調色板:使用圖像中存在的顏色圖
- TrueColor:使用標準配色方案之一(今天最有可能是 sRGB)
- ColorSeparation:不確定,但我認為它單獨儲存通道
- |上述之一|Matte:強制存在 Alpha 通道。
注意:按照今天的標準,在sRGB色彩空間或灰色色彩空間中寫入灰度圖像之間的差異幾乎可以忽略不計。(並且使用純 RGB 代替 sRGB 也可以忽略不計,並且圖像通常會顯示很差。不要使用純 RGB,使用 sRGB。)
返回圖片
現在我們可以解釋 IM 做出的決定,我們可以爭辯說是image1.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)
我們可以看到image1.png有一個
PaletteAlpha
類型(或者PaletteMatte
在 IM 術語中),而image2有一個GrayscaleAlpha
類型。image1.png沒有顏色圖的事實是完全錯誤的。因此,錯誤的圖像編寫器必須將該圖像寫入具有顏色圖但沒有將顏色圖寫入圖像。
當 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
,您將獲得PseudoClass,Graysclae,Gray圖像,這可能會為您節省少量字節(在 100-500k 的典型 Web 圖像上可能節省 10-20k),但代價是不兼容的格式。例如,我pygtk
有時對PseudoClass圖像感到厭惡,我猜它缺乏向後兼容性。