Image Format and Color Conversion Using ImageMagick

用 ImageMagick 轉換圖檔格式和顏色

【摘要】用 ImageMagick 將 svg 向量圖檔轉換為 png 格式,並改變顏色與尺寸。另外也敘述了將轉換好的圖示製成佈景的方法。


【目錄】

    【前言
    【準備工作
    【彩色圖的轉換
    【灰階圖的轉換一
    【灰階圖的轉換二
    【黑白圖的轉換
    【處理不改變顏色者
    【製成 Icon Theme
    【附錄——選項原文

【前言】

一、起因於想要有綠色系列的圖示,但圖示通常有數百個,不可能全部自製,所以就用最簡單的方法,將系統原有的圖示改為綠色。


二、顏色通常可大致分為彩色、黑白、灰階三類。想用一種方法將這三類都轉換為綠色,似乎不太可能。所以下文將分為三部分,分別說明快速轉換這三類圖檔的方法。(其實這三個方法只有些微的不同。)


三、想要快速轉換數百個圖檔不太可能用圖形界面程式,所以本例用指令行的 ImageMagick,版本是 6.9.10-23 Q16 x86_64 20190101。作業系統是自己組合的 FluxBox Debian GNU/Linux 10。來源圖示是 Humanity Icon Theme,在 /usr/share/icons/Humanity/ 目錄中。


四、四年多前曾發表過「圖檔顏色的轉換」,當時是用 Inkscape 轉換圖檔格式,再用 ImageMagick 改變顏色和尺寸。近日改寫為只用 ImageMagick 指令,記錄於此。


五、轉換原則:

  • 為了減少失真,原檔只用可任意縮放的 .svg 格式。
  • 為了減少邊緣的瑕疵,先做較大的圖再縮小。
  • 為了減少麻煩,不分類,全放在一起。

【準備工作】

一、在自己家新增目錄,舉例如 ${HOME}/Pictures/svg:

mkdir ${HOME}/Pictures/svg

二、將來源圖示目錄中想用的 .svg 檔全部複製到此目錄。

  • 不要選 links。
  • 不須分類,全放在一起。
  • 同名即略過。

如果所有的 .svg 檔都要,可用:

find /usr/share/icons/Humanity -type f -name *.svg -exec cp '{}' ${HOME}/Pictures/svg \;

三、在這個 svg/ 目錄中建立五個子目錄,分別放紅色(含橙、黃、紫色)、藍靛色、黑白、灰階、不變的(綠色和維持原色).svg 檔。這要花一些時間慢慢分。檔案管理員用顯示縮圖的樣式,才好分類。

cd ${HOME}/Pictures/svg; mkdir red blue bw gray keep

【彩色圖的轉換】

此法是改變色調 (hue),故對黑白圖無效。請將以下指令存成 color.sh 檔,執行 bash color.sh

#!/bin/bash
 # 將彩色的 .svg 檔轉為綠色的 .png 檔
 
 # 指定 .svg 檔所在路徑
SVGPATH=${HOME}/Pictures/svg/red
 
 # 新增所需目錄
cd ${SVGPATH}
mkdir green
cd green
mkdir 256 96 64 48 32 24 16
cd ${SVGPATH}
 
for fname in $(ls *.svg)
do
  # 用 ImageMagick 將 .svg 檔轉為 256x256 的 .png(第一行),再改為綠色(第二行)
  convert -background none -density 512 ${SVGPATH}/${fname} \
    -modulate 100,100,160 ${SVGPATH}/green/256/$(basename ${fname} .svg).png
done
 # -background:指定背景色;none 為透明
 # -density:指定尺寸;本例使用的來源圖示是 48x48 px 的 svg 檔
 #   -density 設成 512,所得的 png 是 256x256 px;各位要自己檢查
 # -modulate 後的三個數字分別設定亮度、飽和度、色調。
 #   就 "紅橙黃綠藍靛紫" 的順序來看,-modulate 的第三個數字,
 #   若大於 100,顏色會往右移,例如:原為綠色,會往紫色方向改變;
 #   若小於 100,則往左移,如原為綠色,會往紅色方向改變;
 #   與 100 差距愈大,變化就愈大。
 #   160 可將紫、紅、橙、黃色改為綠色。
 #   50 可將藍、靛色改為綠色。
 #   所以,上例較適合紅色系的圖,含紫、橙、黃色。
 #   藍、靛色就改用 SVGPATH=${HOME}/Pictures/svg/blue 和 -modulate 100,100,50。
 
cd ${SVGPATH}/green
 
 # 縮小
for fname in $(ls 256)
do
  for SIZE in 16 24 32 48 64 96
  do
    convert 256/${fname} -resize ${SIZE}x${SIZE} ${SIZE}/${fname}
  done
done
 
 # 刪除暫存目錄
rm -r 256
 
exit

color-demo

【灰階圖的轉換一】

一、內容和彩色的大同小異,差在改顏色的方法,在此介紹 -clut-colorize 兩種選項,先介紹前者。至於顏色則示範深、淺兩種綠色。


二、-clut 選項,是對照一參考圖,將原灰階圖中較深色的地方改成參考圖較上方的顏色,原圖較白處改成參考圖較下方的顏色。也就是說,原圖由黑到白改成參考圖由上到下的顏色。所以,(1)參考圖是什麼顏色,結果就是什麼顏色;(2)若要較順,參考圖要用漸層色。請將以下指令存成 gray1.sh 檔,執行 bash gray1.sh

#!/bin/bash
 # 將灰階的 .svg 檔轉為綠色的 .png 檔
 
 # 設定 .svg 檔所在路徑
SVGPATH=${HOME}/Pictures/svg/gray
 
 # 新增所需目錄
cd ${SVGPATH}
mkdir green
cd green
mkdir dark light
cd dark
mkdir 256 96 64 48 32 24 16
cd ../light
mkdir 256 96 64 48 32 24 16
cd ${SVGPATH}
 
 # 建立參考圖
 # 深色
convert -size 10x100 gradient:#060-#fff /tmp/g060.png
 # 淺色
convert -size 10x100 gradient:#0a0-#fff /tmp/g0a0.png
 # 參考圖做成 10x100 是為了讓有興趣的人能看清楚,其實只要 1x10 就可以了
 # 中間的顏色,程式會自動計算出來
 
for fname in $(ls *.svg)
do
  convert -background none -density 512 ${SVGPATH}/${fname} \
    /tmp/g060.png -clut -sharpen 0x3 -modulate 100,200,100 \
    ${SVGPATH}/green/dark/256/$(basename ${fname} .svg).png
  convert -background none -density 512 ${SVGPATH}/${fname} \
    /tmp/g0a0.png -clut -sharpen 0x3 -modulate 100,200,100 \
    ${SVGPATH}/green/light/256/$(basename ${fname} .svg).png
done
 # 用 ImageMagick 將 .svg 檔轉為 256x256 的 .png(第一行),再改為綠色(第二行)
 # -background:指定背景色;none 為透明
 # -density:指定尺寸;本例使用的來源圖示是 48x48 px 的 svg 檔
 #   -density 設成 512,所得的 png 是 256x256 px;各位要自己檢查
 # -clut:以後圖為參考取代前圖的顏色 channel 值
 # -sharpen 選項是為了讓結果更清晰
 # -modulate 改飽和度能使顏色更鮮艷
 
cd ${SVGPATH}/green
 
 # 縮小
for fname in $(ls dark/256)
 # 只是提供檔名,所以在 dark 或 light 其中之一即可
do
  for SIZE in 16 24 32 48 64 96
  do
    convert dark/256/${fname} -resize ${SIZE}x${SIZE} dark/${SIZE}/${fname}
    convert light/256/${fname} -resize ${SIZE}x${SIZE} light/${SIZE}/${fname}
  done
done
 
 # 刪除暫存目錄
rm -r dark/256 light/256
 
exit

gray-demo

【灰階圖的轉換二】

-colorize 選項是依 -fill 選項所設定的顏色和 -colorize 的設定值來轉換顏色。請將以下指令存成 gray2.sh 檔,執行 bash gray2.sh

#!/bin/bash
 # 將灰階的 .svg 檔轉為綠色的 .png 檔
 
 # 設定 .svg 檔所在路徑
SVGPATH=${HOME}/Pictures/svg/gray
 
 # 新增所需目錄
cd ${SVGPATH}
mkdir green
cd green
mkdir dark light
cd dark
mkdir 256 96 64 48 32 24 16
cd ../light
mkdir 256 96 64 48 32 24 16
cd ${SVGPATH}
 
for fname in $(ls *.svg)
do
  convert -background none -density 512 ${SVGPATH}/${fname} \
    -fill white -colorize 0,33,0 ${SVGPATH}/green/dark/256/$(basename ${fname} .svg).png
  convert -background none -density 512 ${SVGPATH}/${fname} \
    -fill white -colorize 0,66,0 ${SVGPATH}/green/light/256/$(basename ${fname} .svg).png
done
 # 用 ImageMagick 將 .svg 檔轉為 256x256 的 .png(第一行),再改為綠色(第二行)
 # -background:指定背景色;none 為透明
 # -density:指定尺寸;本例使用的來源圖示是 48x48 px 的 svg 檔
 #   -density 設成 512,所得的 png 是 256x256 px;各位要自己檢查
 # -fill:填充色
 # -colorize:依設定值和 -fill 所設定的顏色來上色
 #   設定值是紅、綠、藍的百分比,範圍 +/-100,用逗號分開,範例請見上面指令
 #   -fill 用白色是 (255,255,255),所以 33% 會比 66% 深。
 
cd ${SVGPATH}/green
 
 # 縮小
for fname in $(ls dark/256)
 # 只是提供檔名,所以在 dark 或 light 其中之一即可
do
  for SIZE in 16 24 32 48 64 96
  do
    convert dark/256/${fname} -resize ${SIZE}x${SIZE} dark/${SIZE}/${fname}
    convert light/256/${fname} -resize ${SIZE}x${SIZE} light/${SIZE}/${fname}
  done
done
 
 # 刪除暫存目錄
rm -r dark/256 light/256
 
exit

【黑白圖的轉換】

一、黑白圖示大多在高對比目錄中。


二、轉換方法和灰階的一樣,兩種皆可。但因黑白圖只有兩種顏色,所以用 -colorize 比較合理。只要把路徑改成 SVGPATH=${HOME}/Pictures/svg/bw 即可,其餘指令都一樣。


black-white-demo

【處理不改變顏色者】

不改變顏色的包括原本即是綠色的和欲維持原色的。這些也要改成 .png 格式和所需的尺寸。請將以下指令存成 keep.sh 檔,執行 bash keep.sh

#!/bin/bash
 # 將 .svg 檔轉為 .png 格式和所需的尺寸
 
 # 指定 .svg 檔所在路徑
SVGPATH=${HOME}/Pictures/svg/keep
 
 # 新增所需目錄
cd ${SVGPATH}
mkdir green
cd green
mkdir 256 96 64 48 32 24 16
cd ${SVGPATH}
 
for fname in $(ls *.svg)
do
  # 用 ImageMagick 將 .svg 檔轉為 256x256 的 .png 格式
  convert -background none -density 512 ${SVGPATH}/${fname} \
    ${SVGPATH}/green/256/$(basename ${fname} .svg).png
done
 # -background:指定背景色;none 為透明
 # -density:指定尺寸;本例使用的來源圖示是 48x48 px 的 svg 檔
 #   -density 設成 512,所得的 png 是 256x256 px;各位要自己檢查
 
cd ${SVGPATH}/green
 
 # 縮小
for fname in $(ls 256)
do
  for SIZE in 16 24 32 48 64 96
  do
    convert 256/${fname} -resize ${SIZE}x${SIZE} ${SIZE}/${fname}
  done
done
 
 # 刪除暫存目錄
rm -r 256
 
exit

【製成 Icon Theme】

圖示都處理好了,要如何使用呢?

一、將每一顏色的 green/ 目錄合併,移到 ${HOME}/.icons/ 目錄中。

mkdir ${HOME}/.icons/Green
cd ${HOME}/Pictures/svg
mv bw/green/dark/* ${HOME}/.icons/Green
for SIZE in 16 24 32 48 64 96
do
  mv --force gray/green/dark/${SIZE}/* ${HOME}/.icons/Green/${SIZE}
  mv --force blue/green/${SIZE}/* ${HOME}/.icons/Green/${SIZE}
  mv --force red/green/${SIZE}/* ${HOME}/.icons/Green/${SIZE}
  mv --force keep/green/${SIZE}/* ${HOME}/.icons/Green/${SIZE}
done

二、在 ${HOME}/.icons/Green/ 目錄新增 index.theme 檔,其內容如下:

[Icon Theme]
Name=Green
Comment=Green
Inherits=gnome,hicolor
Example=folder
Directories=16,24,32,48,64,96,

[16]
Size=16
Context=All
Type=Fixed

[24]
Size=24
Context=All
Type=Fixed

[32]
Size=32
Context=All
Type=Fixed

[48]
Size=48
Context=All
Type=Fixed

[64]
Size=64
Context=All
Type=Fixed

[96]
Size=96
Context=All
Type=Fixed

三、修改設定檔

㈠ 開啟 ${HOME}/.gtkrc-2.0,修改成下行:

gtk-icon-theme-name = "Green"

㈡ 開啟 ${HOME}/.config/gtk-3.0/settings.ini,修改成下行:

gtk-icon-theme-name = Green

【附錄——選項原文】

列出本例有使用的 ImageMagick 選項之原文供參考。


-background color
Set the background color.

The color is specified using the format described under the -fill option. The default background color (if none is specified or found in the image) is white.

-clut
Replace the channel values in the first image using each corresponding channel in the second image as a color lookup table.

The second (LUT) image is ordinarily a gradient image containing the histogram mapping of how each channel should be modified. Typically it is a either a single row or column image of replacement color values. If larger than a single row or column, values are taken from a diagonal line from top-left to bottom-right corners.

The lookup is further controlled by the -interpolate setting, which is especially handy for an LUT which is not the full length needed by the ImageMagick installed Quality (Q) level. Good settings for this are the ‘bilinear’ and ‘bicubic’ interpolation settings, which give smooth color gradients, and the ‘integer’ setting for a direct, unsmoothed lookup of color values.

This operator is especially suited to replacing a grayscale image with a specific color gradient from the CLUT image.

Only the channel values defined by the -channel setting will have their values replaced. In particular, since the default -channel setting is RGB, this means that transparency (alpha/matte channel) is not affected, unless the -channel setting is modified. When the alpha channel is set, it is treated by the -clut operator in the same way as the other channels, implying that alpha/matte values are replaced using the alpha/matte values of the original image.

If either the image being modified, or the lookup image, contains no transparency (i.e. -alpha is turned ‘off’) but the -channel setting includes alpha replacement, then it is assumed that image represents a grayscale gradient which is used for the replacement alpha values. That is you can use a grayscale CLUT image to adjust a existing images alpha channel, or you can color a grayscale image using colors form CLUT containing the desired colors, including transparency.

See also -hald-clut which replaces colors according to the lookup of the full color RGB value from a 2D representation of a 3D color cube.

-colorize value
Colorize the image by an amount specified by value using the color specified by the most recent -fill setting.

Specify the amount of colorization as a percentage. Separate colorization values can be applied to the red, green, and blue channels of the image with a comma-delimited list of colorization values (e.g., -colorize 0,0,50).

-density width
-density widthxheight
Set the horizontal and vertical resolution of an image for rendering to devices.

This option specifies the image resolution to store while encoding a raster image or the canvas resolution while rendering (reading) vector formats such as Postscript, PDF, WMF, and SVG into a raster image. Image resolution provides the unit of measure to apply when rendering to an output device or raster image. The default unit of measure is in dots per inch (DPI). The -units option may be used to select dots per centimeter instead.

The default resolution is 72 dots per inch, which is equivalent to one point per pixel (Macintosh and Postscript standard). Computer screens are normally 72 or 96 dots per inch, while printers typically support 150, 300, 600, or 1200 dots per inch. To determine the resolution of your display, use a ruler to measure the width of your screen in inches, and divide by the number of horizontal pixels (1024 on a 1024×768 display).

If the file format supports it, this option may be used to update the stored image resolution. Note that Photoshop stores and obtains image resolution from a proprietary embedded profile. If this profile is not stripped from the image, then Photoshop will continue to treat the image using its former resolution, ignoring the image resolution specified in the standard file header.

The -density option sets an attribute and does not alter the underlying raster image. It may be used to adjust the rendered size for desktop publishing purposes by adjusting the scale applied to the pixels. To resize the image so that it is the same size at a different resolution, use the -resample option.

-fill color
color to use when filling a graphic primitive.

This option accepts a color name, a hex color, or a numerical RGB, RGBA, HSL, HSLA, CMYK, or CMYKA specification. See Color Names for a description of how to properly specify the color argument.

Enclose the color specification in quotation marks to prevent the “#" or the parentheses from being interpreted by your shell.

For example,

-fill blue
-fill "#ddddff"
-fill "rgb(255,255,255)"

See -draw for further details.

To print a complete list of color names, use the -list color option.

-modulate brightness[,saturation,hue]
Vary the brightness, saturation, and hue of an image.

The arguments are given as a percentages of variation. A value of 100 means no change, and any missing values are taken to mean 100.

The brightness is a multiplier of the overall brightness of the image, so 0 means pure black, 50 is half as bright, 200 is twice as bright. To invert its meaning -negate the image before and after.

The saturation controls the amount of color in an image. For example, 0 produce a grayscale image, while a large value such as 200 produce a very colorful, ‘cartoonish’ color.

The hue argument causes a “rotation" of the colors within the image by the amount specified. For example, 50 results in a counter-clockwise rotation of 90, mapping red shades to purple, and so on. A value of either 0 or 200 results in a complete 180 degree rotation of the image. Using a value of 300 is a 360 degree rotation resulting in no change to the original image.

For example, to increase the color brightness by 20% and decrease the color saturation by 10% and leave the hue unchanged, use -modulate 120,90.

Use -set attribute of ‘option:modulate:colorspace’ to specify which colorspace to modulate. Choose from HCL, HCLp, HSB, HSI, HSL (the default), HSV, HWB, or LCH (LCHuv). For example,

convert image.png -set option:modulate:colorspace hsb -modulate 120,90 modulate.png

-resize geometry
Resize an image.

See Image Geometry for complete details about the geometry argument. Offsets, if present in the geometry string, are ignored, and the -gravity option has no effect.

If the -filter option or -define filter:option=value precedes the -resize option, the image is resized with the specified filter.

Many image processing algorithms assume your image is in a linear-light coding. If your image is gamma-corrected, you can remove the nonlinear gamma correction, apply the transform, then restore it like this:

convert portrait.jpg -gamma .45455 -resize 25% -gamma 2.2  \
-quality 92 passport.jpg

-sharpen radius
-sharpen radiusxsigma
sharpen the image.

Use a Gaussian operator of the given radius and standard deviation (sigma).

-size width[xheight][+offset]
set the width and height of the image.

Use this option to specify the width and height of raw images whose dimensions are unknown such as GRAY, RGB, or CMYK. In addition to width and height, use -size with an offset to skip any header information in the image or tell the number of colors in a MAP image file, (e.g. -size 640×512+256).

For Photo CD images, choose from these sizes:

192x128
384x256
768x512
1536x1024
3072x2048

發表留言