<tr valign="top">
<td width="8"><img alt="" height="1" width="8" src="http://www.ibm.com/i/c.gif"/></td>
<td width="16"><img alt="" width="16" height="16" src="http://www.ibm.com/i/c.gif"/></td>
<td class="small" width="122">
<p><span class="ast">未顯示需要 JavaScript 的文檔選項</span></p>
</td>
</tr>
級別: 初級
Michael , 高級軟件工程師
2004 年 4 月 05 日
沒有什么能象命令行工具這樣適合于處理大批量的任務,對于圖像操作也不例外。Web 開發(fā)人員和管理員會喜歡輕松處理大量文件的能力,無論是使用命令行還是腳本。程序員 Michael Still 介紹了 ImageMagick 套件,這是一個用于以多種格式對圖像進行縮放大小、旋轉、轉換和其它操作的 Linux 工具箱,無論圖像的數(shù)量是一個還是上百個,它都可以一次處理掉。
本文展示了如何使用命令行工具執(zhí)行圖像操作。這種任務對我而言相當常見,因為我擁有幾部數(shù)碼相機,并且現(xiàn)在管理著一個擁有幾千張精彩照片的資料庫。對于經(jīng)常需要對大量圖像進行批處理的 Web 開發(fā)人員和管理員而言,命令行工具是特別具有吸引力的選擇,因為開發(fā)人員可以將它們合并成腳本。但即使您只想執(zhí)行一兩次操作,選擇命令行也可以節(jié)省時間。
本文中討論的命令行工具是優(yōu)秀的 ImageMagick 套件的一部分,該套件是隨 Red Hat Linux 一起提供的,并可免費在線下載(請參閱 參考資料 )。也可以通過 C、C++、Perl、Python、Java 和其它幾種語言使用 ImageMagick,Linux 程序員會喜歡這樣做。
請注意,有許多種方法可以完成本文中所討論的任務。我討論了我所使用的方法,它對我確實很有效。這并不意味著除此之外的其它工具就很差勁;僅僅表示我對于現(xiàn)在所使用的工具很滿意。
本文采用了以具體問題作為示例進行討論這種形式,但其思想應該也適用于其它問題領域。
生成縮略圖
我對照片集所執(zhí)行的第一個操作是生成縮略圖。我還想減少圖像的大小,以適用于網(wǎng)站版本因為許多人實際上并不想看到我兒子的 1920 x 1440 像素的照片。
我使用 convert 工具,它是 ImageMagick 套件的一部分。 convert 確實很酷。除了圖像縮放,它還具有平滑處理、均衡圖像組、模糊化、在圖像格式間進行轉換、修剪、去斑濾鏡、抖動、繪制邊界、翻轉、連接、重新采樣、調(diào)整大小以及許多功能。查看聯(lián)機幫助頁以獲取關于它的各種命令行選項的更多信息。本文稍后還討論了 convert 所提供的許多在視覺上比較有趣的效果。
讓我們假定我希望為這幅非常美麗的玫瑰圖像制作縮略圖:
圖 1. 玫瑰的照片
要用 convert 調(diào)整圖像的大小,只要使用 -sample 命令行選項。例如,讓我們假定我希望得到 80 x 40 像素的縮略圖。則命令行將是:
# convert -sample 80x40 input.jpg output.jpg
這生成了如下的縮略圖:
圖 2. 生成縮略圖的第一次嘗試
ImageMagick 會自動地考慮在縮放圖像大小時圖像的兩條鄰邊所產(chǎn)生的比例。這意味著新的圖像的高寬比與原圖相同。在上面的示例中,這意味著縮放后的圖像實際上是 53 x 40 像素,而不是所要求的 80 x 40 像素。指定輸出圖像大小的另一種方法是使用百分數(shù)。如果您不能確定輸入圖像的大小,或者并不是刻意地要得到確切大小的新圖像,那么這種方法比較方便。以下是關于如何使用百分數(shù)的示例:
# convert -sample 25%x25% input.jpg output.jpg
現(xiàn)在,我們得到了如下所示的縮略圖:
圖 3. 生成縮略圖的第二次嘗試
使用該命令,您可以在某個目錄中生成圖像的縮略圖。雖然本文并不是關于 shell 腳本編制的,但我會迅速地向您展示一個示例,以說明如何生成當前目錄中每個 JPEG 的縮略圖:
清單 1. 為當前目錄中的所有 JPEG 生成縮略圖
for img in `ls *.jpg`
do
convert -sample 25%x25% $img thumb-$img
done
這會生成一系列大小為實際圖像 25% 的縮略圖,其文件名稱是在 JPEG 文件名的前面加上 thumb- 前綴。
獲取關于圖像文件的信息
另一個常見任務是確定圖像文件的尺寸(dimension)。例如,您可能需要知道前一個示例中的縮略圖有多大。
許多圖像處理庫提供了用于此用途的優(yōu)秀工具。例如,libtiff(TIFF 庫,我先前曾寫過有關這個庫的文章;請參閱 參考資料 )提供了 tiffinfo , tiffinfo 顯示了關于 TIFF 文件的下列種類的信息:
清單 2. tiffinfo 的樣本輸出
TIFF Directory at offset 0x146
Image Width: 352 Image Length: 288
Bits/Sample: 8
Compression Scheme: Deflate
Photometric Interpretation: RGB color
Samples/Pixel: 3
Planar Configuration: single image plane
這并不是一個關于如何使用 tiffinfo 的詳盡示例,但您可以看到它返回了諸如圖像大小、像素深度(每個樣本的位數(shù)和每個像素的樣本數(shù)的組合)以及所用的壓縮方案之類的有用信息。
類似地,有一個返回 PNG 文件的類似信息的 pnginfo 命令:
清單 3. pnginfo 的樣本輸出
sample.png...
Image Width: 640 Image Length: 480
Bitdepth (Bits/Sample): 8
Channels (Samples/Pixel): 3
Pixel depth (Pixel Depth): 24
Colour Type (Photometric Interpretation): RGB
Image filter: Single row per byte filter
Interlacing: No interlacing
Compression Scheme: Deflate method 8, 32k window
Resolution: 0, 0 (unit unknown)
FillOrder: msb-to-lsb
Byte Order: Network (Big Endian)
Number of text strings: 0 of 0
我不清楚是否存在用于其它格式(諸如 BMP、GIF 和 JPEG)功能相當?shù)膯蝹€工具。但是,ImageMagick 又一次幫了我們的忙,這次是使用名為 identify 的工具。
# identify -verbose sample.png
清單 4. identify 的樣本輸出
Image: sample.png
Format: PNG (Portable Network Graphics)
Geometry: 640x480
Class: DirectClass
Type: true color
Depth: 8 bits-per-pixel component
Colors: 142360
Filesize: 555.6k
Interlace: None
Background Color: grey100
Border Color: #DFDFDF
Matte Color: grey74
Dispose: Undefined
Iterations: 0
Compression: Zip
signature: 361fe70ae623ef6f1fca44e0d29d157c2d701039fcf0f8625862925d881e13a4
Tainted: False
User Time: 0.190u
Elapsed Time: 0:01
您可以看到 identify 顯示了一串關于圖像文件的有用信息,如以像素為單位的圖像大小、圖像的色深以及圖像的格式。
pnginfo
當我開始使用 PNG 時,我成為 libtiff 用戶已經(jīng)有相當長一段時間了。當時,沒有與 tiffinfo 功能相當?shù)墓ぞ哂糜?PNG 文件,因此我編寫了 pnginfo 。(您可以通過 參考資料 中的鏈接下載 pnginfo )。
identify 還有 -format 命令行標志,它允許您僅指定想要輸出的信息。例如,如果您只對圖像尺寸感興趣,則可以使用如下命令:
# identify -format "%wx%h" sample.png
輸出類似于:
此處, %w 表示圖像寬度,而 %h 表示圖像高度。有關可以與該選項一起使用的格式化字符的更多信息,請查看 identify 聯(lián)機幫助頁。
旋轉圖像
另一種經(jīng)常需要用到的圖像操作是旋轉圖像。例如,我用數(shù)碼相機所拍攝的許多照片都旋轉了九十度,因為我是把相機豎過來拍攝它們的。相機不會為我旋轉這些照片,因此我編寫了一個腳本,以便在從相機下載這些圖像之后完成旋轉任務。
例如,這是我在最近去塔斯馬尼亞島的亞瑟港旅游時拍攝的一幅照片:
圖 4. 橫臥的亞瑟港
為了旋轉該照片,我們再次求助于 convert 命令:
# convert -rotate 90 input.jpg output.jpg
該命令生成了如下所示的圖像:
圖 5. 亞瑟港
請注意 -rotate 選項的參數(shù)是將圖像向右旋轉的度數(shù)。要向左旋轉,請使用負數(shù)。
更改圖像的格式
convert 命令還能夠轉換圖像文件的格式。這包括圖像格式之間的轉換(如將 JPEG 圖像轉換成 PNG)以及從顏色到灰度之間的轉換、抖動和類似操作。
convert 根據(jù)命令行中給定的文件擴展名來了解輸入和輸出的圖像格式分別是什么。因此,要將 JPEG 轉換成 PNG,使用如下所示的命令行:
# convert input.jpg output.png
在我撰寫本文時,ImageMagick 支持 89 種圖像格式。查看 ImageMagick 網(wǎng)站(請參閱 參考資料 )以獲取更多信息。
向圖像添加文本注釋
有時您需要向圖像添加文本注釋。例如,假設您的公司擁有標準的名片圖像,并希望在將名片發(fā)送到打印機之前將每個雇員的詳細信息都添加到名片上面。另一個示例是為通過您網(wǎng)站上的在線課程的用戶生成表示證書(presentation certificate)。
讓我們假定您從這幅圖入手:
圖 6. 2002 年芙蘿莉雅蝶園藝博覽會(FLORIADE 2002)照片
您可以使用下列命令行,為該圖注釋一些標識信息:
# convert -font helvetica -fill white -pointsize 36
-draw ‘text 10,50 "Floriade 2002, Canberra, Australia"‘
floriade.jpg comment.jpg
這里是結果:
圖 7. 加注釋的 2002 年芙蘿莉雅蝶園藝博覽會照片
迄今為止,這是我在本文中所展示的最復雜的 convert 命令行了,因此我將花些時間來解釋它。
-font helvetica 將注釋的字體設置為 Helvetica。也可以在此處指定字體文件的路徑。這個示例給圖像添加了標記,這樣未經(jīng)許可其它網(wǎng)站就不能再使用該圖像了,但它是使用位于非標準位置的字體來完成該任務的:
# convert -font fonts/1900805.ttf -fill white -pointsize 36 \ -draw ‘text 10,475 ""‘ \ floriade.jpg stillhq.jpg
以下是結果:
圖 8. 帶標記的圖像
-fill white 用白色而不是標準的黑色來填充字母。
-pointsize 36 以點為單位指定字母的大小。一英寸等于 72 點。
-draw ‘text 10,50 "..."‘ 是一組繪圖命令,在本例中是移動到位置 10, 50,然后繪制出雙引號中的文本。使用單引號是因為如果需要繪制多個字,則繪圖命令中需要使用雙引號,而您不能在雙引號中再用雙引號。
其它更富藝術性的轉換
convert 還實現(xiàn)了一系列相當藝術性的轉換。我將在此處演示一些在視覺上比較有趣的轉換。如果您對此感興趣,應該查看 ImageMagick 的聯(lián)機幫助頁和網(wǎng)站以獲取更多信息。這是我將用于該演示的輸入圖像:
圖 9. 烏奴奴(Uluru)夕照
這張烏奴奴(以前稱為艾爾斯巖(Ayers Rock))的照片是在日落時分照的。
炭筆
炭筆效果模擬出該圖像的素描畫。
# convert -charcoal 2 input.jpg output.jpg
其結果如下所示:
圖 10. 應用炭筆效果之后的烏奴奴夕照
增加 -charcoal 選項的參數(shù)的數(shù)值會增加應用于該圖像的“炭筆”數(shù)量,但也會延緩生成圖像的過程。下面是一個使用稍多炭筆的示例。
# convert -charcoal 10 input.jpg output.jpg
它產(chǎn)生了如下結果:
圖 11. 應用更多炭筆效果之后的烏奴奴夕照
如果您真的想近乎瘋狂地使用大量炭筆:
# convert -charcoal 200 input.jpg output.jpg
您會得到這樣的結果:
圖 12. 應用過量炭筆效果之后的烏奴奴夕照
指定三個值
要指定三個值,每個值分別代表紅色、綠色和藍色三個采樣,使用 red/green/blue 形式的參數(shù)。例如, 10/20/30 意味著紅色的值是 10、綠色值為 20 而藍色值為 30。您也可以在這個構造中使用百分數(shù)。
著色
著色 是將每個像素的顏色與指定顏色混合的過程。該效果的參數(shù)就是要用來混合的顏色。可以用一個百分數(shù)(它將分別用于紅色、綠色和藍色),也可以用三個百分數(shù)來指定這個參數(shù)。也可以提供三個實際值中的一個。
# convert -colorize 255 input.jpg output.jpg
以下是著色之后的烏奴奴:
圖 13. 應用著色效果之后的烏奴奴夕照
內(nèi)爆(Implode)
內(nèi)爆效果模擬了您圖像的中心被吸入虛擬黑洞的情形。所用的參數(shù)是您所期望的內(nèi)爆效果量。
# convert -implode 4 input.jpg output.jpg
內(nèi)爆的烏奴奴如下所示:
圖 14. 內(nèi)爆之后的烏奴奴夕照
solarize 參數(shù)
ImageMagick 文檔聲明 solarize 的參數(shù)總是百分數(shù)。嚴格地說,這并不正確。如果參數(shù)以百分號結尾,那么就把它當作百分數(shù)。否則,就將它當作一個字面值。
曝光
曝光是在相片沖洗過程中把底片暴露在光線中所發(fā)生的效果。這里,輸入?yún)?shù)是應用于該效果的亮度,可以指定為絕對值,也可以是可用于像素的最大可能值的百分數(shù)。如果像素超過閾值,則對它求反。
# convert -solarize 42 input.jpg output.jpg
在曝光之后,我們的圖像如下所示:
圖 15. 曝光之后的烏奴奴夕照
發(fā)散
spread 在圖像之內(nèi)以隨機的數(shù)量移動像素。所用的參數(shù)是被移到新選擇的位置的像素區(qū)域的大小。所以它指定了輸出和輸入的相似程度:
# convert -spread 5 input.jpg output.jpg
再次使用烏奴奴,這次是發(fā)散之后的情形:
圖 16. 發(fā)散之后的烏奴奴夕照
在一次 ImageMagick 調(diào)用中執(zhí)行多條命令
您已經(jīng)看到了將命令與注釋示例聯(lián)系起來的示例。但是,可以將本文中提到的任意 ImageMagick 命令鏈接起來。例如,也許我們希望制作某圖像的縮略圖,然后對它應用發(fā)散。在發(fā)散發(fā)生之后,我們將應用炭筆效果:
# convert -sample 25%x25% -spread 4 -charcoal 4 input.jpg output.jpg
這會產(chǎn)生:
圖 17. 應用了一系列效果之后的烏奴奴
圖像操作技巧
在迫不及待地動手修改您所擁有的每一幅圖像之前,您應該記住一些關于圖像操作的事情。首先,您應該考慮一下打算長期使用什么圖像格式,免得最終有了一大堆某種格式的圖像之后再來后悔就晚了。這一點特別容易做到,因為正如本文先前所討論的,您可以使用 convert 來更改圖像的格式。
JPEG 壓縮對于諸如照片之類的大圖像很適合。但其壓縮通常是 有損的 (換句話說,在壓縮過程中會丟棄圖像數(shù)據(jù))。這使得 JPEG 非常不適于壓縮需要保持字跡清晰的文本。另一件需要牢記的事情是:損失是累積的。
如果您不希望在一系列操作之后產(chǎn)生的累積損失會影響到彩色圖像的圖像品質,通常 PNG 是個不錯的選擇。
有關該主題的更多信息,請參閱我所著的關于用 libtiff 處理彩色圖像的文章“ Graphics programming with libtiff,Part 2”(請參閱下面的 參考資料 中的鏈接)。
您還應該記住本文中所展示的大多數(shù)操作是單向的。例如,如果您將圖像縮小了,則圖像數(shù)據(jù)就丟失了。如果此后您再放大該圖像,則輸出將很粗糙。例如,讓我們拍一幅照片,制作縮略圖,然后再擴大該圖像。為了節(jié)省一些篇幅,在此,我將只包括最初和最后的圖像,而省略中間的縮略圖。
圖 18. 凱恩斯瀑布
現(xiàn)在,我們將把縮小和放大操作鏈接在一起:
# convert -sample 10% -sample 1000% input.jpg output.jpg
這產(chǎn)生了如下所示的圖像:
圖 19. 斑駁的瀑布
很難在最終的圖像中看出瀑布來,盡管分散您的眼光似乎有些幫助。
結束語
在本文中我們討論了一些有趣的事情,ImageMagick 可以完成這些任務以滿足您的命令行圖像處理需求。這里所描述的工具并不能解決所有問題,有時您會需要定制代碼段,但是通用的命令行圖像處理工具通??梢源蠓鹊販p輕工作負擔。
參考資料
關于作者
Michael 已在圖像處理領域工作了好多年,包括為澳大利亞政府部門管理和開發(fā)大型圖像數(shù)據(jù)庫的幾年。目前,他正在為 Tower Software 工作,該公司制造名為 TRIM 的世界領先的 EDMS 和記錄管理軟件包。Michael 還是名為 Panda 的開放源碼 PDF 生成 API 以及一系列其它開放源碼的開發(fā)人員??赏ㄟ^ mikal@ 與 Michael 聯(lián)系。