在 Linux 系統下,ImageMagick 提供了強大的命令列影像處理能力。結合 Bash 指令碼,可以將繁瑣的影像操作自動化,提升效率。本文將介紹如何使用 identify 命令取得影像尺寸,以及如何編寫 Bash 指令碼實作新增浮水印、邊框和生成縮圖等功能。這些指令碼可作為日常影像處理的利器,尤其適用於需要批次處理大量影像的場景。
讓電腦說話:使用 sayit 指令碼
在 macOS 系統中,有一個內建的語音合成工具叫 say,可以用來讀出文字內容。雖然這個工具功能強大,但使用起來可能稍嫌複雜。因此,我們可以建立一個包裝指令碼 sayit,讓它變得更容易使用。
指令碼內容
#!/bin/bash
# sayit--使用 "say" 指令讀出指定的文字(僅限 macOS)
dosay="$(which say) --quality=127"
format="$(which fmt) -w 70"
voice="" # 預設系統語音
rate="" # 預設語速
demovoices()
{
# 列出所有可用的語音並示範每種語音。
voicelist=$(say -v \? | grep "en_" | cut -c1-12 | sed 's/ /_/;s/ //g;s/_$//')
if [ "$1" = "list" ]; then
echo "可用語音:$(echo $voicelist | sed 's/ /, /g;s/_/ /g')" | $format
echo "小技巧:使用 \"$(basename $0) demo\" 聆聽所有語音"
exit 0
fi
for name in $voicelist; do
myname=$(echo $name | sed 's/_/ /')
echo "語音:$myname"
$dosay -v "$myname" "你好!我是 $myname。這是我說話的聲音。"
done
exit 0
}
usage()
{
echo "用法:sayit [-v 語音] [-r 速度] [-f 檔案] 文字"
echo " 或:sayit demo"
exit 0
}
while getopts "df:r:v:" opt; do
case $opt in
d) demovoices list ;;
f) input="$OPTARG" ;;
r) rate="-r $OPTARG" ;;
v) voice="$OPTARG" ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -eq 0 -a -z "$input" ]; then
$dosay "嘿!你沒有給我任何引數。"
echo "錯誤:未指定引數。請指設定檔案或文字。"
exit 0
fi
if [ "$1" = "demo" ]; then
demovoices
fi
if [ ! -z "$input" ]; then
$dosay $rate -v "$voice" -f $input
else
$dosay $rate -v "$voice" "$*"
fi
exit 0
程式碼解密:
- 指令碼初始化:定義了
dosay和format命令,分別用於語音合成和文字格式化。 demovoices函式:列出所有可用的英語語音,並示範每種語音說話的聲音。- 使用
say -v \?命令取得所有語音列表。 - 使用
grep、cut和sed處理列表,使其變成可用於迴圈的格式。
- 使用
usage函式:顯示指令碼的使用方法。- 引數解析:使用
getopts解析命令列引數,支援-v(語音)、-r(語速)、-f(檔案)和-d(列出語音)選項。 - 執行語音合成:根據引數決定是讀取檔案內容還是直接讀出指定的文字。
如何運作
- 使用
say -v \?取得系統中所有可用的語音。 - 對語音列表進行處理,使其變成適合指令碼使用的格式。
- 示範每種語音的發音。
執行指令碼
由於指令碼會產生聲音輸出,因此無法直接在書中展示結果。你需要自己執行指令碼來體驗效果。
結果展示
$ sayit -d
可用語音:Agnes, Albert, Alex, Bad News, Bahh, Bells, Boing, Bruce, Bubbles, Cellos, Daniel, Deranged, Fred, Good News, Hysterical, Junior, Karen, Kathy, Moira, Pipe Organ, Princess, Ralph, Samantha, Tessa, Trinoids, Veena, Vicki, Victoria, Whisper, Zarvox
小技巧:使用 "sayit.sh demo" 聆聽所有不同的語音
$ sayit "Yo, yo, dog! Whassup?"
$ sayit -v "Pipe Organ" -r 60 "Yo, yo, dog! Whassup?"
$ sayit -v "Ralph" -r 80 -f alice.txt
結果分析:
- 列出所有可用語音:使用
-d選項可以列出所有支援的英語語音。 - 使用不同語音和語速:可以指定不同的語音和語速來讀出文字。
改進方向
- 改進語言編碼的匹配規則,以正確處理所有語音。
- 將指令碼擴充套件為守護程式,能夠在特定事件發生時自動讀出通知。
影像處理與ImageMagick的強大功能
在Linux世界中,命令列具有多種強大的功能,但由於其根據文字的特性,似乎很難處理圖形。不過,事實並非如此。ImageMagick是一個功能強大的命令列工具套件,幾乎可以在任何命令列環境中使用,從OS X到Linux等。為了使用本章中的指令碼,你需要從http://www.imagemagick.org/下載並安裝該套件,或者透過像apt、yum或brew這樣的套件管理器進行安裝。
更聰明的影像尺寸分析工具
file命令可以確設定檔案型別,在某些情況下還可以確定影像的尺寸。但是,它對於JPEG檔案常常無能為力。為瞭解決這個問題,我們可以使用ImageMagick中的identify工具來更準確地取得影像尺寸。
程式碼解析
#!/bin/bash
# imagesize--使用ImageMagick的identify工具顯示影像檔案資訊和尺寸
for name
do
identify -format "%f: %G with %k colors.\n" "$name"
done
exit 0
內容解密:
identify命令:這是ImageMagick套件中的一個工具,用於識別影像檔案的格式和特性。-format選項:允許自定義輸出格式。在這個例子中,%f代表原始檔案名,%G代表影像的尺寸(寬度×高度),%k代表影像中使用的最大顏色數量。- 迴圈遍歷輸入檔案:指令碼對每個輸入的檔案名執行
identify命令,並按照指定的格式輸出資訊。
為影像新增浮水印
保護線上影像的一種方法是新增浮水印。雖然有些藝術家不喜歡在照片上新增版權影像或其他識別資訊,但使用ImageMagick可以輕鬆實作這一點,甚至可以批次處理。
程式碼解析
#!/bin/bash
# watermark--在輸入影像上新增指定的文字作為浮水印,並將輸出儲存為image+wm
wmfile="/tmp/watermark.$$.png"
fontsize="44"
trap "$(which rm) -f $wmfile" 0 1 15
if [ $# -ne 2 ] ; then
echo "Usage: $(basename $0) imagefile \"watermark text\"" >&2
exit 1
fi
if [ ! -r "$1" ] ; then
echo "$(basename $0): Can't read input image $1" >&2
exit 1
fi
dimensions="$(identify -format "%G" "$1")"
convert -size $dimensions xc:none -pointsize $fontsize -gravity south \
-draw "fill black text 1,1 '$2' text 0,0 '$2' fill white text 2,2 '$2'" \
$wmfile
suffix="$(echo $1 | rev | cut -d. -f1 | rev)"
prefix="$(echo $1 | rev | cut -d. -f2- | rev)"
內容解密:
wmfile變數:定義了一個臨時檔案,用於儲存浮水印疊加層。trap命令:確保在指令碼離開時刪除臨時檔案。dimensions變數:使用identify命令取得輸入影像的尺寸。convert命令:用於建立浮水印疊加層,並將其與原始影像合成。-size選項:指定輸出影像的尺寸。xc:none:建立一個透明背景。-pointsize和-gravity:控制文字大小和浮水印的位置。-draw選項:用於繪製浮水印文字。這裡使用了三層文字(黑色和白色)來建立一個具有立體效果的浮水印。
使用ImageMagick處理圖形檔案
ImageMagick是一款功能強大的影像處理工具,可以用於建立、編輯和合成影像。在本章中,我們將探討如何使用ImageMagick來處理圖形檔案,包括新增水印和邊框。
新增水印
新增水印是一種保護影像版權的有效方法。我們可以使用ImageMagick的composite命令來新增水印。
水印指令碼
#!/bin/bash
# watermark - 新增水印到影像檔案
prefix=$(echo "$1" | rev | cut -d. -f2- | rev)
suffix=$(echo "$1" | rev | cut -d. -f1 | rev)
wmfile=$(mktemp)
convert -size "$(identify -format "%G" "$1")" xc:none -font Arial -pointsize 44 -fill grey -draw "text 10,50 '$2'" "$wmfile"
newfilename="$prefix+wm.$suffix"
composite -dissolve 75% -gravity south "$wmfile" "$1" "$newfilename"
echo "建立了新的帶水印影像檔案$newfilename。"
exit 0
內容解密:
prefix=$(echo "$1" | rev | cut -d. -f2- | rev):取得輸入影像檔名的字首。- 使用
rev命令反轉檔名,然後使用cut命令提取檔案字首。
- 使用
suffix=$(echo "$1" | rev | cut -d. -f1 | rev):取得輸入影像檔案的字尾。- 同樣使用
rev和cut命令提取檔案字尾。
- 同樣使用
wmfile=$(mktemp):建立一個臨時檔案來儲存水印影像。convert -size "$(identify -format "%G" "$1")" xc:none -font Arial -pointsize 44 -fill grey -draw "text 10,50 '$2'" "$wmfile":建立水印影像。- 使用
identify命令取得輸入影像的大小。 - 使用
convert命令建立一個與輸入影像大小相同的水印影像,並在其中繪製指定的文字。
- 使用
composite -dissolve 75% -gravity south "$wmfile" "$1" "$newfilename":將水印影像與輸入影像合成。- 使用
composite命令將水印影像疊加到輸入影像上,透明度設為75%,並置於底部。
- 使用
新增邊框
除了新增水印外,我們還可以使用ImageMagick的convert命令來為影像新增邊框或框架。
邊框指令碼
#!/bin/bash
# frameit - 為影像檔案新增邊框或框架
usage() {
cat << EOF
用法:$(basename $0) -b border -c color imagename
或 $(basename $0) -f frame -m color imagename
EOF
exit 1
}
while getopts "b:c:f:m:" opt; do
case $opt in
b) border="$OPTARG"; ;;
c) bordercolor="$OPTARG"; ;;
f) frame="$OPTARG"; ;;
m) mattecolor="$OPTARG"; ;;
?) usage; ;;
esac
done
shift $(($OPTIND - 1))
if [ $# -eq 0 ]; then
usage
fi
if [ ! -z "$bordercolor" -a ! -z "$mattecolor" ]; then
echo "$0: 不能同時指定顏色和墊色。" >&2
exit 1
fi
if [ ! -z "$frame" -a ! -z "$border" ]; then
echo "$0: 不能同時指定邊框和框架。" >&2
exit 1
fi
if [ ! -z "$border" ]; then
args="-bordercolor $bordercolor -border $border"
else
args="-mattecolor $mattecolor -frame $frame"
fi
for name in "$@"; do
suffix="$(echo "$name" | rev | cut -d. -f1 | rev)"
prefix="$(echo "$name" | rev | cut -d. -f2- | rev)"
newname="$prefix+f.$suffix"
echo "為影像$name新增邊框,儲存為$newname"
convert "$name" $args "$newname"
done
exit 0
內容解密:
while getopts "b:c:f:m:" opt; do:解析命令列引數。- 使用
getopts命令解析選項和引數。
- 使用
if [ ! -z "$bordercolor" -a ! -z "$mattecolor" ]; then:檢查是否同時指定了顏色和墊色。- 如果同時指定了,則輸出錯誤資訊並離開。
if [ ! -z "$frame" -a ! -z "$border" ]; then:檢查是否同時指定了框架和邊框。- 如果同時指定了,則輸出錯誤資訊並離開。
for name in "$@"; do:遍歷所有輸入的影像檔名。- 對每個檔名,提取字首和字尾,並生成新的檔名。
convert "$name" $args "$newname":使用convert命令為影像新增邊框或框架。- 根據指定的引數,使用
-border或-frame選項為影像新增邊框或框架。
- 根據指定的引數,使用
影像處理自動化:ImageMagick 與縮圖生成
在數位時代,影像處理已成為網站管理與數位內容創作中的重要環節。ImageMagick 作為一款強大的影像處理工具,提供了豐富的功能來簡化影像編輯流程。本文將探討如何利用 ImageMagick 實作影像邊框新增及縮圖生成自動化。
新增影像邊框:frameit 指令碼解析
在介紹 frameit 指令碼之前,我們先了解其主要功能:為影像新增指定樣式的邊框。該指令碼利用 ImageMagick 的 convert 命令實作複雜的邊框效果。
程式碼重點解析
suffix="$(echo $image | rev | cut -d. -f1 | rev)"
prefix="$(echo $image | rev | cut -d. -f2- | rev)"
newname="$prefix+f.$suffix"
內容解密:
檔案名稱處理:指令碼首先對輸入的檔案名稱進行解析,將其分解為字首和字尾。
- 使用
rev命令將檔名反轉。 - 透過
cut命令提取副檔名和主檔名。 - 將結果再次反轉以還原正確的順序。
- 使用
新檔名生成:將字首與新的識別符號
+f結合,形成新的檔名。
命令執行邏輯
convert "$1" -mattecolor $mattecolor $frameargs -frame $framesize "$newname"
內容解密:
引數設定:
$1代表輸入的影像檔案。-mattecolor指定邊框的顏色。$frameargs包含了邊框樣式的引數。-frame $framesize定義了邊框的大小和樣式。
輸出檔案:轉換後的影像儲存為
$newname。
縮圖生成:thumbnails 指令碼詳解
thumbnails 指令碼提供了一個更靈活的縮圖生成方案,支援精確尺寸或比例縮放。
主要功能特點
引數控制:
-e引數用於指定精確的縮圖尺寸。-f引數允許縮圖按比例縮放到指定的最大尺寸內。-s引數可去除 EXIF 資訊,使影像更適合網路使用。
自動化處理:指令碼可批次處理多個影像檔案。
程式碼實作重點
if [ -z "$fit" ] ; then
size="$exact!"
echo "Creating ${rwidth}x${rheight} (exact size) thumb for file $image"
else
size="$fit"
echo "Creating ${rwidth}x${rheight} (max size) thumb for file $image"
fi
convert "$image" $strip $convargs "$size" "$newname"
內容解密:
尺寸計算邏輯:
- 若使用
-f引數,則縮圖按比例縮放。 - 若使用
-e引數,則強制縮圖到指定尺寸(可能改變比例)。
- 若使用
convert命令引數說明:$strip用於移除 EXIF 資訊。$convargs包含了-unsharp 0x.5和-resize等引數,用於最佳化縮圖品質。
影像處理的最佳實踐
- 批次處理:利用指令碼可大幅提高影像處理的效率。
- 引數靈活性:透過不同的引陣列合,可以滿足多樣化的影像處理需求。
- 自動化 EXIF 資訊移除:提高影像在網路上的安全性與適配性。