ImageMagick 範例 --
文字轉圖像處理

索引
ImageMagick 範例 前言與索引
ImageMagick 中的文字運算符
標籤 - 簡單文字標籤
標題 - 自動換行標籤
 
文字屬性和設定
文字參數中的特殊跳脫字元
Pango - 基本格式化文字
文字 - 純文字頁面
Postscript/PDF - 文件轉圖像
 
繪製 - 在現有畫布上繪製文字
註釋 - 更好的文字繪製
 
字體路徑(開發中)
確定字體指標
建立混合字體樣式的線條
表單填寫 - 圖像上的分層文字欄位
文字處理替代方案
建立文字標籤或將文字添加到圖像可能是 ImageMagick 最基本和最常用的操作之一。它也是最簡單的操作之一,但可以產生一些非常棒的效果。因此,這是一個開始探索 IM 功能的好地方。

ImageMagick 中的文字運算符

ImageMagick 提供了許多種在影像中繪製文字的方式,展現了這個影像處理函式庫的多功能性。本頁詳細介紹了繪製文字的特定方法和樣式。在您研究這些範例時,請務必牢記 ImageMagick 主要是一個影像轉換器和修改器。因此,所提供的每種方法都是簡單的文字繪製運算子,例如在影像中新增標籤和版權訊息。請參閱標註影像。所有文字運算子也都理解和使用一組標準文字處理設定,例如「-font」、「-pointsize」。還有「-fill」顏色設定,以及用於更複雜文字繪製的「-strokewidth」、「-stroke」和「-undercolor」顏色。如果您實際建立新的影像(例如標籤和標題),則也會使用「-background」顏色設定。最後是更新的「-kerning」和「-interword-spacing」修飾符。ImageMagick 並非 一個完整的格式化文字和文件處理器。如果您需要進行大量的文字處理,最好使用完整的互動式文字處理器,或像「TeX」這樣的批次文字格式化程式(或其變體之一)(請參閱下面的完整的文字處理系統)。這些程式的輸出(通常是 PostScript 格式)可以轉換為影像,並透過 ImageMagick 進一步修改。也就是說,針對正確的工作使用正確的工具。話雖如此,還是可以進行一些混合字體處理。如需入門,請參閱本頁底部附近的建立混合字體樣式的線條。現在,讓我們來看看將文字融入影像的基本方法。在下一節(複合字體)中,我們將探討如何產生一些有趣的字體效果。

標籤 - 簡單文字標籤

基本標籤

使用「label:」影像建立字體影像是 ImageMagick 中快速繪製字體的較典型方法。最大的優點是它會根據目前的「-background」和「-fill」顏色設定產生自己的畫布,並調整大小以符合繪製的文字。例如,以下是一個典型的產生的標籤。

  magick -background lightblue -fill blue \
          -font Candice -pointsize 72 label:Anthony \
          label.gif
[IM Output]
以上可能是最典型的 label 用法,透過選擇字體和「-pointsize」來定義結果。但这远非生成文本标签最有趣的方式。
產生的「label:」影像也會有設定為相同字串的「label影像屬性中繼資料。某些檔案格式(例如 MIFF 和 PNG)會儲存該特定屬性,並可在後續的影像處理程式中使用。有關使用「label」中繼資料的範例,請參閱使用儲存的中繼資料進行蒙太奇以取得範例。
如果您還指定了「-size」,則會以該大小建立產生的標籤影像。

  magick -background lightblue -fill blue  -font Candice \
          -size 165x70 -pointsize 24 label:Anthony     label_size.gif
[IM Output]
您也可以使用「-gravity」來設定標籤在較大方塊中的位置。

  magick -background lightblue -fill blue  -font Candice \
          -size 165x70  -pointsize 24  -gravity center \
          label:Anthony     label_gravity.gif
[IM Output]
當然,如果您沒有為標籤設定「-size」,則生成的「label:」中將沒有額外的空間供「-gravity」使用,這使得它相當無用。同時使用「-size」和「-pointsize」的問題在於文字可能會「溢出」指定的圖像大小。

  magick -background lightblue -fill blue  -font Candice \
          -size 165x70  -pointsize 72  -gravity center \
          label:Anthony     label_overflow.gif
[IM Output]
在 6.5.2-4 版本之前,如果同時給出了「-size」設定,IM 會完全忽略「-pointsize」設定。這會導致上圖中的文字根據「最佳擬合」處理自動調整大小(請參閱下一組範例)。

最佳圖像擬合

使用標籤生成特定「-size」圖像的最大訣竅是「不要」為標籤指定「-pointsize」。發生這種情況時,IM 將可以自由嘗試並選擇「最適合」請求的圖像大小的字體大小。也就是說,繪製的文字將被調整以適應給定的大小!

  magick -background lightblue -fill blue  -font Candice \
          -size 165x70  label:Anthony     label_size_fit.gif
[IM Output]
如您所見,通過設定「-size」設定,您最終可能會在圖像的右側或下方留出一些額外的空間。
當 IM 建立「最佳擬合」標籤時,它使用的實際點大小也會儲存在「label:pointsize圖像屬性 中,讓您以後可以使用該資訊。這是 IM v6.6.2-7 在論壇討論 點大小報告 期間添加的。
您仍然可以通過調整「-gravity」設定來調整標籤在該額外空間中的位置。

  magick -background lightblue -fill blue  -font Candice \
          -size 165x70 -gravity center label:Anthony     label_size_gravity.gif
[IM Output]
當然,如果您沒有為標籤設定「-size」,則生成的「label:」中將沒有額外的空間供「-gravity」使用,因此只有在您要求圖像具有特定大小時才有意義。現在是最棒的消息。如果您為標籤提供的「-size」設定僅包含寬度或高度,則字體將調整為最適合該給定尺寸。然後,未指定的另一個維度將自動調整以適應該文字!

  magick -background lightblue -fill blue -font Candice \
          -size 160x  label:Anthony     label_size_width.gif
[IM Output]
基本上,這意味著上面的「label:」將始終為 160 像素寬,並使用該寬度的最大字體大小。然後將調整標籤的高度以適應。如果指定了高度但未指定寬度,則將執行相同的操作。

  magick -background lightblue -fill blue -font Candice \
          -size x40  label:Anthony     label_size_height.gif
[IM Output]
此標籤高 40 像素,文字的未定義點大小已調整以適應該高度,然後未定義的寬度已設定為適應繪製的文字。完全如您所料。當然,在這種情況下,任何「-gravity」設定幾乎沒有額外的空間可以使用。

多行標籤

label:」生成器可以(從 IM 版本 6.2.5 開始)生成多行標籤。

  magick -background lightblue  -fill blue  -font Ravie -pointsize 20 \
          label:'ImageMagick\nRules - OK!'     label_multiline.gif
[IM Output]
如您所見,「label:」將「\n」的使用理解為表示換行符。這表示您可能必須預先處理您的輸入文字,以確保在將資料放在命令列上時轉義任何特殊字元。有關更多詳細資訊,請參閱下面的 文字參數中的特殊轉義字元。由於「-gravity」也會影響「label:」的生成(從 IM 版本 6.2.6 開始),因此您可以使用它來「對齊」多行標籤。

  magick -background lightblue -fill blue -font Corsiva -pointsize 24 \
          -gravity center    label:'ImageMagick\nExamples\nby Anthony' \
          label_centered.gif
[IM Output]
IM 的一個重要特性是它可以讀取文字資料並從檔案中使用。 這是透過在檔案名稱前面加上一個「@」字元「@」來完成的,並將其用作字串參數。 例如,我們在這裡從我的工作站的「每日訊息」檔案建立一個標籤...


magick -background lightblue -fill blue \ label:@/etc/motd label_file.gif
[IM Output]
您也可以從標準輸入管道讀取標籤的文字。 例如,在這裡,我將報價產生器的輸出轉換為多行標籤。

  mesgs ImageResolution |\
    magick -background lightblue  -fill blue \
            label:@-   label_file_multiline.gif
[IM Output]
請注意,我使用的檔名只是一個「-」字元。 這表示檔案將從標準輸入讀取。 請記住,您可以使用「@filename」將任何命令列字串參數讀入 IM。 這包括以下給出的所有其他文字輸入方法。 但是,它只能用於替換整個字串參數,而不能替換字串參數的一部分。另請注意,在上面的範例中,在標籤影像中添加了一個額外的空白行。此空白行是由輸入文字檔案中的最後一個換行符號引起的。除非您以某種方式從輸入檔案中刪除最後一個換行符號(有關修復此問題的方法,請參閱下面的 caption: 範例),否則「label:」將始終包含輸入文字檔案中的空白行。
大多數舊版本的 IM(v6.2.5 之前)都不處理多行標籤。在這些版本中,這些行將被附加在一起,形成一個非常非常長的單行。

垂直標籤

當然,您也可以在輸入文字中添加換行符號。例如,在這裡,我採用一個簡單的單詞,並在每個字母之間添加一個換行符號,以建立一些居中的垂直文字。

  echo -n "Vertical" | sed 's/./&@/g; s/@$//' | tr '@' '\012' |\
    magick -background lightblue -fill blue -font Ravie -pointsize 24 \
            -gravity center    label:@-   label_vertical.gif
請注意,「sed」命令在每個字元後添加一個「@」字元,但在字串末尾除外。「tr」然後用換行符號替換「@」字元。它還假設輸入文字不以換行符號結尾,這會導致在結果影像的底部添加一個額外的空格。
[IM Output]
執行 Linux 的使用者,因此使用 GNU 版本的「sed」命令,可以刪除「tr」,並在 sed 命令中將「@」替換為「\n」,以便它直接在每個字元之間插入換行符號。另請參閱特殊屬性 行距,可用於調整字元間距。

標題 - 自動換行標籤

在多數方面,「caption:」影像(來自文字輸入產生器)與「label:」完全相同,只是它不會擴展文字大小以適應指定的「-size」設定,而是會將不適合指定「-size」寬度的任何長行自動換行。「-size」設定不是可選的,但必須至少指定以像素為單位的最大寬度。例如,以下是一個長行的標題,它不適合指定的寬度。

  magick -background lightblue  -fill blue  -font Corsiva -pointsize 36 \
          -size 320x   caption:'This is a very long caption line.' \
          caption.gif
[IM Output]
產生的「caption:」影像還將具有設定為相同字串的「caption影像屬性 中繼資料,允許您稍後重複使用該資訊。所有常見的影像檔案格式都會將此資訊與影像一起儲存。有關範例,請參閱 使用儲存的中繼資料進行蒙太奇
預設情況下,文字都是左對齊的,但是從 IM 版本 6.2.0 開始,「caption:」會為了文字對齊目的而考慮「-gravity」。

  magick -background lightblue  -fill blue  -font Candice -pointsize 40 \
          -size 320x  -gravity Center  caption:'ImageMagick Rules OK!' \
          caption_centered.gif
[IM Output]
如果您確實為「-size」設定提供了高度和寬度,則影像高度也將設定為該高度。然後,您也可以使用「-gravity」設定來垂直定位文字。

  magick -background lightblue  -fill blue  -font Gecko -pointsize 32 \
          -size 320x100  -gravity South caption:'Captions at their height!' \
          caption_height.gif
[IM Output]
但請注意,如果文字的高度超出您使用「-size」和「-pointsize」指定的範圍,文字將會超出邊界。目前的「-gravity」設定將決定文字的哪個部分被截斷。例如,這與前面的範例完全相同,但圖片「-size」的尺寸對於結果來說太小。

  magick -background lightblue  -fill blue  -font Gecko -pointsize 32 \
          -size 320x60  -gravity South caption:'Captions at their height!' \
          caption_height_toosmall.gif
[IM Output]

最佳擬合標題

從 IM v6.3.2 版本開始,如果您同時提供最終圖像的寬度和高度,但沒有定義字體的「-pointsize」(或使用「+pointsize」關閉點大小),IM 將嘗試自動調整字體大小,以便最佳地填滿您要求的圖像「-size」。例如,這裡我要求 ImageMagick 填滿一個相當大的區域…

  magick -background lightblue -fill blue -font Candice -size 320x140 \
          caption:'This text is resized to best fill the space given.' \
          caption_filled.gif
[IM Output]
現在是一個更小、更窄的區域,使用相同的字體和文字字串。

  magick -background lightblue -fill blue -font Candice -size 80x110 \
          caption:'This text is resized to best fill the space given.' \
          caption_filled_sm.gif
[IM Output]
請注意,最後兩個範例之間的唯一區別是生成的圖像的「-size」。IM 會調整文字和自動換行,以便盡可能地填滿指定的圖像大小。這對於將未知的文字片段放入指定的空間非常有用,而不會超出區域邊界。然而,在內部,它相當於多次運行標題,因為 IM 會搜索要使用的正確點大小,以便最佳地填滿指定的空間。換句話說,它通常比您提供特定的「-pointsize」要慢 10 倍甚至更多。

帶有段落的標題

caption:」圖像運算符(從 IM v6.2.5 版本開始)將「\n」外殼轉義符(因此您需要使用雙反斜線「\\」來轉義反斜線)理解為新行或段落。在此版本之前,必須通過單獨的「caption:」操作來處理單獨的段落。

  magick -background lightblue -fill blue \
          -font Ravie -pointsize 24 -size 360x \
          caption:"Here I use caption to wordwrap.\nTwo separate lines." \
          caption_multi_line.gif
[IM Output]
您可以使用「@」檔名前綴從檔案或標準輸入(來自先前的管道命令)讀取要繪製的文字,就像我們對「label:」所做的那樣。

  mesgs FilePrivate |\
    magick -background  lightblue  -fill blue  -pointsize 12 \
            -size 320x  caption:@-  caption_file.gif
[IM Output]
如您所見,輸入文字中的換行符(從 IM v6.2.5 版本開始)將被視為段落分隔符。這包括輸入檔案中的任何最終換行符。當然,「label:」不會對行進行自動換行,而是保留它們。如果您真的希望將檔案視為單個段落,則需要將換行符替換為空格字符,以便您的文字都在同一行上。例如,這裡我們採用相同的文字,但將換行符替換為空格,然後將單詞之間的任何多個空格替換為單個空格…

  mesgs FilePrivate |      tr '\012' ' ' | sed 's/  */ /g' |\
    magick -background  lightblue  -fill blue  -pointsize 12 \
            -size 320x  caption:@-  caption_one_line.gif
[IM Output]
如您所見,這樣做效果更好。但是,您通常希望將空行視為段落分隔符。這意味著您需要刪除所有換行符,但與空行有關的換行符除外。這裡有一個特殊的「sed」命令,可以將此類文字轉換為「caption:」所需的格式。在這種情況下,文字是「magick」手冊頁的第一頁。

  man magick | col -b | expand | \
    sed '/^$/d; :loop y/\n/ /; N; /\n$/! b loop;  s/   */ /g; s/^ //' |\
      head -n 7 |    magick -size 400x  caption:@-  caption_manual.gif
[IM Output]
標題沒有「對齊」文字選項。但pango: 文字格式化程序(使用外部庫)確實具有該功能,以及更多其他功能。

文字屬性

原本會影響文字處理的設定包括:「-font」、「-fill」、「-pointsize」、「-size」和「-gravity」。以上我們已經介紹過許多屬性控制項。但還有其他屬性控制項不常使用,而且原本不會影響「label:」或「caption:」文字影像產生。從 IM v6.3.2 開始,您也可以使用「-stroke」、「-strokewidth」和「-undercolor」。「label:」或「caption:」。例如,我在這裡使用許多不同的設定來控制 IM 文字影像渲染的屬性...

   magick -background white -fill dodgerblue  -font Candice \
           -strokewidth 2  -stroke blue   -undercolor lightblue \
           -size 165x70 -gravity center label:Anthony     label_color.gif
[IM Output]
如需這些設定的詳細資訊,請參閱下方「底色方塊」以及繪圖區段中的「筆畫、筆畫寬度」。
目前,您無法使用「-tile」、「-fill」、「-background」和「-origin」定義的拼貼影像,以及「label:」或「caption:」。只能使用純色。嘗試這樣做只會產生未定義的(黑色)顏色。

點數、密度和實際字體大小

像素是顯示器或影像上的點,而這也是 IM 的運作單位。另一方面,影像會以特定的解析度列印(以「每英寸點數」(dpi) 或每英寸像素數 (ppi) 指定)。因此,影像解析度會影響其他程式將影像調整為特定媒體大小的方式。例如:它會影響真實世界中影像的實際大小。影像的解析度(密度或 dpi)與影像的像素大小以及影像在記憶體或磁碟上佔用的空間無關。一般而言,它也與大多數 IM 影像操作無關。因此,對 ImageMagick 而言,解析度只是儲存在影像中的一組數字,通常會被忽略。影像解析度或密度唯一相關的情況是字體,以及將向量格式(如 PostScript、PDF、MWF)轉換為 IM 處理的光柵影像格式。「-density」設定會告知 IM 輸出裝置上每英寸有多少像素(點數)(ppi),然後它可以使用此設定來調整影像產生和字體大小以符合。例如,IM 預設使用「-density」設定為 72 ppi,這是顯示器或網頁上顯示影像的典型設定。由於字體大小是以「點」為單位指定(使用「-pointsize」),並且根據定義 1 點是 1/72 英吋,因此 72 點的字體應該會產生大約 1 英吋高的文字...

  magick -pointsize 72 label:Hello  pointsize.gif
[IM Output]
然而,大多數現代顯示器的解析度都比這更好,通常介於每英寸 90 到 120 個像素 (ppi) 之間。因此...

  magick -density 90 -pointsize 72 label:Hello  density.gif
[IM Output]
應該會在 90 dpi 的顯示器上產生一個 1 英吋高的標籤。它就在我的顯示器上!您可以在螢幕上測量這些影像的高度,以檢查顯示器的解析度。由於每英吋的像素數較多,繪製的字體在影像中的像素數方面自然也較大,因此會產生較大的影像。不同的影像程式通常具有不同的預設密度,這可能會導致字體在由不同程式繪製時出現差異,即使點數相同。請注意,「-pointsize」實際上是指字體的**行距**(實際上是其繪製區域高度),而不是指繪製字母的實際高度!因此,在相同的點數和密度下,一種字體可能會比另一種字體看起來更大或更小。實際上只有字體的行距會相同,其他任何內容都取決於字體和字體設計師。因此,使用預設的「-density」72dpi(其中 1 點 = 1 像素),12 點字體在兩行文字的基線之間應該有 12 個像素的間距。
請注意,生成的「標籤:」影像的高度基於影像的繪製區域或邊界框,通常是字體的行距和點數。但情況並非總是如此,因此僅垂直附加文字行實際上是不正確的字體處理方式!
有些字體甚至可能會超出正常的行距邊界,延伸到行距之上或更常見的是之下。手寫字體尤其如此。字體的**外觀**也會受到字體的「-pointsize」和「-density」的影響。將字體點數加倍(「-pointsize 24」)也會產生一個看起來與密度或解析度加倍的字體大小相同的字體。但是,由於字體的設計方式,較大點數的字體中線條的粗細可能不會發生太大變化。也就是說,較大的字體大小略有不同。但如果僅將密度加倍(「-density 144」),則 12 點字體將以其尺寸加倍的方式繪製,看起來應該仍然像原始的 12 點字體,只是以更大的比例繪製,邊緣更平滑。但是,在非常低的解析度下,像素的物理尺寸限制也可能會影響字體的外觀。這意味著由於密度定義的像素尺寸較大,因此在較低密度下細線可能會變粗。'density' 和 'pointsize' 之間的關係是一個非常複雜的問題,只有專業的字體圖形設計師才能完全理解,並設計他們的字體來正確處理。根據 IM 論壇 中的 Lithium 的說法...
我認為這是 TrueType 字體渲染器的一個特性。TrueType 字形不僅僅是一組曲線,它可能包含多個細節級別和指令,這些指令會根據以像素為單位的輸出大小調整點坐標,這在以像素為單位的較小尺寸下更為明顯。正因為如此,小字體看起來與縮小的大字體不同(而且更清晰,可以注意到)。
FUTURE 範例:相同「像素」大小、但不同密度和點數大小的字體之間的差異。基本上,增加其中一個因素同時減少另一個因素相同的量可能*不會*產生相同的結果。特別是在線條粗細和字體的整體「樣式」方面。您最好針對您正在做的事情調整正確的因素。在為輸出裝置縮放字體時或稍後調整字體大小時,請使用「-density」,並使用「-pointsize」進行正常的字體大小變更。如果您想進一步了解字體,請參閱《TrueType 字體基本知識 (PDF)》文件,我發現它非常有趣。

標籤圖像邊界

使用某些特殊字體時,該字體可能會使用擴展字元,而過去 IM 在為這些字體建立標籤時遇到很多麻煩。也就是說,文字會溢出提供的畫布。例如,以下是「LokiCola」字體中的兩個大寫字母,讓人聯想到某個著名的汽水品牌。

  magick -background lightblue -fill blue -font LokiCola -pointsize 64 \
          label:HC  label_overflow_font.gif
[IM Output]
如您所見,IM 成功地將此字體包含在標籤中,而不會切斷字體的前導或尾隨圖形。
在 IM v6.3.2 之前,「label:」會在上述範例中切斷「H」的前導線以及兩個字元的尾部部分。
之所以存在這個問題,是因為字體的「字形」或字元描述繪製在特定字母的字體定義邊界之外,允許它們與字體中的其他字元重疊(通常在上方或下方)。這是字體本身設計和定義方式的問題,不是 IM 的錯,儘管 IM 現在為了使用者的最大利益處理這些奇怪的情況。在其他情況下,它仍然可能是一個問題,並且由於多行文字交互作用而無法簡單解決。如需更多資訊,請參閱下方的邊界框溢出範例,以獲得更精確的描述。

Unicode 或 UTF8 格式文字

這種將字串參數提供給 IM 的方法非常重要,因為它允許您執行通常很難從命令列完成的事情。具體而言,處理「Unicode 文字」或使用字元代碼選擇特定字元。現在,如果您可以在命令或腳本中輸入 Unicode 字元,則可以直接使用它們。

  magick -background lightblue -fill blue -pointsize 32 \
          label:' é è à ù ç Ö ÿ ‘ ’ “ ” ° ² ³ € x ÷ '    label_i8n.gif
[IM Output]
但是,很少有人為處理Unicode 字元輸入正確設定了鍵盤或編輯器。即使您不能直接輸入 Unicode 字元,一個簡單的解決方案就是從現有的 UTF-8 文字檔或網頁「複製並貼上」所需的字元。我就是這麼做的!如果您想要繪製的 UTF-8 文字已經生成,則可以使用「@filename」直接從檔案中讀取它。例如,我在這裡從UTF-8 編碼的中文文字檔(檔案中沒有最後的換行符)建立中文標籤。

  magick -background lightblue -fill blue -pointsize 48 \
          -font ZenKaiUni label:@chinese_words.utf8   label_utf8.gif
[IM Output]
上述範例中使用的字體是一種特殊字體,其中定義了完整的中文字形集,例如 Fedora Linux 字體「SimSun」(或字體檔案「gkai00mp.ttf」)、「ZenKaiUni」(位於檔案「ukai.ttf」中)或「ShanHeiSunUni」(位於任何「uming.ttf」或「zysong.ttf」或「bsmi00lp.ttf」檔案中)。

請注意,Windows 字體「Mincho」(在後面的範例中使用)也定義了許多中文字形,但並不完整。如果您將其與上述內容一起使用,則會在未定義的字形處看到一些問號。

特殊的腳本「imagick_type_gen」用於查找、提取字體的正確名稱,並將字體添加到 ImageMagick 的「type.xml」設定檔中。

我們也可以使用「GNU」的「printf」程式(在 Linux 系統上)從 unicode 字元碼產生 UTF-8 字串,將 unicode 數字轉換為特定的 UTF-8 編碼字串,在本例中是正確排版的左引號和右引號(同樣在 UTF-8 輸入中沒有最後的換行符)。例如,這裡我使用 unicode 字元碼產生 UTF-8 文字,並使用命令管道(使用「@-」從「stdin」讀取)而不是從實際檔案中讀取它。

  env LC_CTYPE=en_AU.utf8 \
    printf "\u2018single\u2019 - \u201Cdouble\u201D" | \
      magick -background lightblue -fill blue -pointsize 36 \
              label:@-  label_quotes.gif
[IM Output]
在其他系統(如 Mac OSX 和 Windows)上,您可以使用 perl 的「printf」從 unicode 字元碼輸出 UTF-8 編碼的字元字串。

  perl -e 'binmode(STDOUT, ":utf8"); \
    print "\x{201C}Unicode \x{2018}\x{263A}\x{2019} Please\x{201D}";' |\
      magick -background lightblue -fill blue -pointsize 36 \
              label:@-  label_unifun.gif
[IM Output]
有關更多資訊以及如何查詢各種語言和符號的 unicode 字元碼,請參閱Unicode 字元碼表。unicode 字元不僅可以包含國際字元,而且使用正確的字體,您還可以可以使用它定義的特殊「符號」集。其中最著名的是「DingBats」符號字體。這種字體已經變得非常普遍,現在它是標準 Unicode 字體集的一部分。例如,這裡我使用一個我編寫的特殊「graphics_utf」shell 腳本來提取「DingBats」unicode 符號區域的前 24 個字元,以產生一個 unicode 字元的「塊」作為 UTF-8 文字。

  graphics_utf -N 2701 2718 |\
    magick -font Mincho -pointsize 32 label:@-   label_dingbats.gif
[IM Output]
上面問號是 unicode 或 Windows「Mincho」字體中未定義的特定字元。更具體地說,原始「dingbat」字體中包含的符號存在於 unicode 中,但使用的 unicode 字元碼與預期的 dingbat 代碼不同。有關更多詳細資訊,以及使用正確 unicode 字元替換「缺少」的 dingbat 字元的引用,請參閱Dingbats Unicode 規範表。許多字體不會顯示問號,而是顯示一個方框或一個空白字元來表示此類未定義的字元。如果您在輸出中看到太多此類字元或缺少字元,則可能應該使用其他字體。作為龐大的 unicode 字元字體的一部分,其他可用的符號集包括:托爾金符文符號、數學符號、羅馬數字、箭頭、盲文和技術符號。這是一個很大的集合,可以使用「graphics_utf」shell 腳本幫助您進行探索。以下是 Microsoft「Mincho」字體可以呈現的 unicode 字元的另一個示例。在本例中,來自「雜項符號」部分...

  graphics_utf -N 2620 2630 |\
    magick -font Mincho   -pointsize 40 label:@- label_misc.gif
[IM Output]
在 DOS 腳本中使用 unicode 比在 UNIX 和 LINUX 中困難得多。Wolfgang Hugemann 在Windows 字元編碼中提供了有關在該環境中使用 unicode 的特殊說明。

符號字體

尋找特殊文字圖像的人更常使用的是特殊的「符號字體」。它們比完整的 unicode 字體要小得多,因為它們僅用一組特定的形狀和圖像替換了正常的標準 ASCII 字元(字母和數字),儘管有時(很少見)它們在拉丁語元字元區域也有更多符號。「DingBat」字體符號最初就是以這種方式開始的,但如上所述,它們現在是 Unicode 字元集的一部分。例如,我比較喜歡使用的一個符號來自「WebDings」字體。它是一個相當漂亮的「彎曲的心形」符號,在該字體定義中替換了正常的「Y」字元...

  magick -size 20x20 -gravity center -font WebDings label:Y label_heart_20.gif
  magick -size 40x40 -gravity center -font WebDings label:Y label_heart_40.gif
  magick -size 60x60 -gravity center -font WebDings label:Y label_heart_60.gif
  magick -size 80x80 -gravity center -font WebDings label:Y label_heart_80.gif
請務必牢記,所有 TrueType 字型實際上都是一種特殊的 向量圖形格式,其中包含多個圖像(每個字元一個)。由於它們是向量圖像,這表示您可以使用「-size」、「-pointsize」和「-density」提供的控制項,以幾乎任何大小(比例)「繪製」字元、形狀或符號。如您在上方所見,「彎曲的心形」可以按照我想要的幾乎任何大小「渲染」。有些字型非常專業。例如,您可以從 IDAutomation 獲取一個名為「IDAutomationHC39M.ttf」的字型檔案,可用於產生條碼。例如...
[IM Output] [IM Output] [IM Output] [IM Output]

  magick -font IDAutomationHC39M -pointsize 16 label:'*314-76*' \
          -bordercolor white -border 5x5  label_barcode.gif
[IM Output]
以下是我出於各種原因收集的各種符號字型中發現的其他一些有趣符號...

  magick -pointsize 48 -font WebDings label:' " _ ~ ) - '  label_webdings.gif
  magick -pointsize 48 -font LittleGidding label:' x o w ' label_ltgidding.gif
  magick -pointsize 48 -font WingDings2      label:'ab'    label_wingdings2.gif
  magick -pointsize 48 -font Zymbols  label:' ? , - I Z '  label_zymbols.gif
  magick -pointsize 48 -font TattoEF  label:' B Y D I H '  label_tatooef.gif
  magick -pointsize 48 -font SoundFX  label:' V 3 t f 9 '  label_soundfx.gif
這只是可用內容的一小部分範例。WWW 上有大量幾乎所有可以想像的符號、形狀或圖像的庫供您瀏覽和下載。
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
請記住,每個繪製的字元都有兩個可以繪製的獨立部分:「填充」區域(我在上方顯示的)和「筆劃」或輪廓,它們看起來可能與填充區域非常不同。這些區域中的每一個都可以單獨繪製,或者以不同的顏色繪製,因此最好以多種方式仔細檢查有希望的符號或形狀。您可能會得到非常驚喜的結果。有關執行此操作的一些範例,請參閱 複合字型、筆劃
許多符號字型的創建者使用簡單的掃描器和點陣圖到向量轉換器來生成形狀,而沒有對圖像或形狀進行適當的設計或清理。在查看此類「掃描」字型時,建議謹慎。

上面顯示的最後一個字型就是「掃描」字型的一個例子,與其他設計更合理的字型相比,它具有較差的「點狀」品質。

字元間距

從 IM v6.4.7-8 開始,您可以使用「-kerning」在文字字串中每個字母之間插入額外的字元間距。例如

  magick -pointsize 12               label:Anthony   label_kerning_0.gif
  magick -pointsize 12 -kerning 1    label:Anthony   label_kerning_1.gif
  magick -pointsize 12 -kerning 2.5  label:Anthony   label_kerning_2.gif
  magick -pointsize 12 -kerning 5    label:Anthony   label_kerning_5.gif
  magick -pointsize 12 -kerning -1   label:Anthony   label_kerning-1.gif
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
請注意,實際的字元間距值可以是浮點值,甚至是負值。有關使用負「-kerning」值的另一個範例,請參閱 連接複合字型 範例。

單詞間距

此外,從 IM v 6.4.8-0 開始,可以使用「-interword-spacing」選項來修改單詞之間使用的空格字元的尺寸。例如

  magick                       label:'I Love IM!'  label_wspace_off.gif
  magick -interword-spacing 1   label:'I Love IM!'  label_wspace_1.gif
  magick -interword-spacing 10  label:'I Love IM!'  label_wspace_10.gif
  magick -interword-spacing 25  label:'I Love IM!'  label_wspace_25.gif
[IM Output] [IM Output] [IM Output] [IM Output]
請注意,您不僅可以增加單詞之間空格字元的尺寸,還可以減少預設尺寸。但是請注意,空格會導致單詞重新對齊到像素邊界(與上面的 字元間距 不同),因此空格設置為零的標籤的輸出仍將與完全不包含空格的標籤不同。字元間距單詞間距 也會影響 IM 自動調整文字字串以適應特定尺寸圖像的能力的結果。

  magick -size 150x                       label:'I Love IM!' label_wsize_of.gif
  magick -size 150x -interword-spacing 25 label:'I Love IM!' label_wsize_25.gif
  magick -size 150x -interword-spacing 50 label:'I Love IM!' label_wsize_50.gif
[IM Output] [IM Output] [IM Output]
設定「-interword-spacing」會造成「空格」字元大小不再隨其他文字大小而改變。因此,當 IM 嘗試找出最佳的「-pointsize」時,每個單字之間的空格大小是固定的,因此在將文字放入指定的固定寬度時,空格大小不會被考慮進去。結果是,「-interword-spacing」的值越大,實際上需要用來將文字行放入相同指定影像寬度的字體大小就越小。可以使用負值,實際上可以使文字重疊,或使用特定字元和字體產生不尋常的效果。但如果設定過於負數,可能會產生未定義的行為。建議您在嘗試此操作時要小心。雖然以上範例不是文字對齊(儘管看起來很像),但您可以使用這些選項作為提供適當文字對齊的起點。如果您真的需要該等級的文字格式化和對齊,那麼最好還是使用其他產生預先格式化文字或 Postscript 的方法,例如基於命令列的「TeX」或「LaTeX」軟體。更好的是,您可以使用 SVG(rsvg 函式庫版本)或 Pango 標記語言(請參閱下文)來產生對齊的文字。

行距

從 IM v6.5.5-8 開始,新增了一個選項「-interline-spacing」。這是根據先前設定,應使用者強烈要求而新增的,並且在許多方面都更有用。基本上,它會在個別的文字行之間新增或減少這麼多像素。也就是說,您可以使用它來擴展或壓縮個別的文字行。舉例來說……

  magick                        label:'First\nSecond'  label_lspace_off.gif
  magick -interline-spacing  5   label:'First\nSecond'  label_lspace_5.gif
  magick -interline-spacing 10   label:'First\nSecond'  label_lspace_10.gif
  magick -interline-spacing 20   label:'First\nSecond'  label_lspace_20.gif
  magick -interline-spacing -5   label:'First\nSecond'  label_lspace-5.gif
  magick -interline-spacing -10  label:'First\nSecond'  label_lspace-10.gif
[IM Output] [IM Output] [IM Output] [IM Output] [IM Output] [IM Output]
要充分利用這個設定,您需要能夠計算特定字體的正常行距。這是「-pointsize」的實際定義,它與目前的解析度或「-density」設定定義了字體的行距。它實際上並沒有定義字體的實際高度或線條粗細,儘管它會影響特定字體的這些方面。因此,以每英吋「72」點的「-density」為例,並且根據定義每英吋有 72 個「點」。您可以計算出 12 點字體的行距為 12 像素。有了這些資訊,您可以使用「-interline-spacing 12」的設定來「雙倍行距」12 點的文字行。這會在行與行之間增加 12 個像素。

  magick -density 72 -pointsize 12 -interline-spacing 12  -font Arial \
          label:'First\nSecond\nThird'  label_lspace_double.gif
[IM Output]
當然,如前所述,對於字距大小,在文字元素之間新增固定數量的像素會導致在使用自動點數大小處理時,文字大小變小。也就是說,如果在沒有「-pointsize」設定的情況下提供最終影像「-size」。

  magick -size x70  -interline-spacing 18  -font Arial \
          label:'First\nSecond\nThird'  label_lspace_size.gif
[IM Output]
使用負行距也可以作為一種粗略的垂直「加粗」線條的方法,只需重複該線條,並減去比基準線間距多 1 個像素即可。

  magick -density 72 -pointsize 12 -interline-spacing -13 -font Arial \
          label:'Bolded Word\nBolded'  label_lspace_vbold.gif
[IM Output]
當然,如果您真的想要兩條線,而不仅仅是加粗文字,這就不管用了。它也適用於固定寬度字體。

文字引數中的特殊跳脫字元

在前面章節中,我們已經介紹過在各種文字引數中使用的特殊跳脫字元。具體來說,您可以使用反斜線 '\' 來跳脫特殊字元,例如換行符號,或者您可以使用百分比 '%' 跳脫字元將額外資訊插入字串中,如 影像屬性 頁面所定義。此外,還有一個特殊的 '@' 跳脫字元,如果在行首使用,將會使用文字引數的其餘部分作為檔名,從指定的檔案(或是在使用 '-' 時從標準輸入)讀取資料。
某些系統(例如 Ubuntu)會使用安全策略停用 '@{file}' 跳脫字元的使用。輸入 magick -list policy 可以查看您的系統上有哪些策略以及它們的設定位置。
這些跳脫字元不僅會影響「-format」(供「magick identify」(以及「-identify」和「info:」)使用),還會影響「label:」和「caption:」文字轉影像產生器的輸出,以及控制影像中繼資料設定選項「-label」、「-comment」、「-caption」。最後,它們也會被「-annotate」使用。
雖然反斜線 '\' 會被「-draw」的 'text' 方法使用,但百分比 '%' 跳脫字元則不會被使用,因為它會干擾 ImageMagick 的 SVG 影像處理。這是 IM 版本 6 建立「-annotate」運算子的原因之一。

關於跳脫字元的另一個重點是,雖然它們用於命令列文字引數,但它們從未應用於從文字檔案讀取的資料中(通常使用 '@' 跳脫字元讀取)。這表示您不需要擔心為文字檔案資料跳脫「跳脫字元」,但也表示如果您需要將資訊插入文字中,則必須在 IM 之外自行處理檔案資料。
保護輸入文字檔案免於跳脫字元處理的功能已於 IM 版本 6.3.3 中完成。
例如,這裡我使用兩種方法設定並回報影像的「標籤」和「註解」中繼資料,這些方法會從來源文字檔案設定該資訊。「info.txt」檔案包含字串 [IM 文字](沒有結尾換行)。

  magick -label   @info.txt  rose:     -format '%l label'   info:
  magick -comment @info.txt  rose:     -format '%c set "'   info:
  magick rose: -set label   @info.txt  -format '%l caption' info:
  magick rose: -set comment @info.txt  -format '%c set "'   info:
[IM Text]
請注意,IM 並沒有展開它使用 '@' 檔案讀取跳脫字元讀取的任何跳脫字元序列。這一點很重要,因為這表示每當 IM 從檔案讀取文字時,它都永遠不會處理該檔案中存在的任何特殊字元。
IM 會將文字檔案讀取為字面文字,不帶任何跳脫字元
遺憾的是,這也包括要讀取的檔案(或串流)中可能存在的任何結尾換行符號!當輸入文字的結尾有換行符號時(一種非常常見的做法),這可能會導致產生的影像中出現額外的「空白」行。例如...

  echo "Anthony" | magick label:@-  label_stdin.gif
[IM Output]
如您所見,標籤不僅包含輸入字串,還包含一個額外的空白行,這是因為「echo」命令在結尾添加了換行字元。如果您不想要該結尾換行符號,則需要自行移除它。然而,這可能是一件棘手的事情,具體取決於文字的來源或建立方式,以及您執行 IM 所使用的 API。最好的方法是盡量不要一開始就產生該結尾換行符號。例如,對「echo」使用 '-n' 旗標。

  echo -n "Anthony" | magick label:@-  label_stdin_2.gif
[IM Output]
或者使用不會添加額外換行符號的功能,除非您明確要求。

  printf "Anthony" | magick label:@-  label_stdin_3.gif
[IM Output]
或者,您可以使用一個巧妙的 perl 單行指令來「刪除」最後的換行符號...

  echo "Anthony" | perl -0777 -pe 's/\n$//' |\
     magick label:@-  label_stdin_4.gif
[IM Output]
在其他 API 中,您可以透過「管道開啟」將文字輸入 IM 命令之前,先尋找最後的換行符號。

使用者定義選項跳脫

一個主要問題是嘗試在其他影像中使用從一個影像轉義的資訊,例如在產生單獨的「標籤:」或「標題:」影像時。這是一個非常困難的問題,目前的解決方案(針對單一影像)是建立一個特殊的「使用者選項」,附加到正在處理的影像。然後,可以在需要時,透過「標籤:」、「標題:」或「-annotate」以百分比轉義序列的形式查詢此「設定」。例如,我在這裡使用內建玫瑰影像中的資訊建立一個全新的標籤影像。然後刪除該資訊來源影像,不過我也可以輕鬆地將新標籤附加到原始影像。

  magick rose: \
          -set option:roseinfo 'rose image\nsize = %w x %h\nwith %k colors' \
          label:'%[roseinfo]'  -delete 0   label_escape.gif
[IM Output]
是的,以上內容很棘手,但這是由於涉及一些內部 IM 核心程式庫限制所致。如需更多詳細資訊,請參閱從其他影像存取資料

跳脫跳脫字元

如果您必須將字串作為參數提供給 IM(尤其是作為 API 呼叫),但不希望 IM 展開轉義字元,則可以使用額外的反斜線「\」簡單地「轉義」所有三個轉義字元。請注意,「@」只有在它是第一個字元時才需要「轉義」,並且為了向後相容性,百分比轉義字元也可以透過加倍來轉義。也就是說,「%%」將產生一個百分比符號。例如...

  magick -background lightblue -fill blue -font Candice -pointsize 48 \
          label:'\@ \\n \% 5%% '    label_escapes.gif
[IM Output]
在 IM 6.3.2 版之前,您無法使用反斜線來轉義初始的「@」以關閉「從檔案讀取」功能。在這種情況下,轉義初始「@」的唯一方法是從檔案中讀取它。這在 API 中不太實際。
以下是「-annotate」的類似「轉義轉義字元」範例...

  magick rose: -fill white -stroke black  -font Candice  -pointsize 20 \
          -gravity center   -annotate 0 '\@ \\n 5%%'  annotate_escapes.gif
[IM Output]
當然,如前所示,從檔案讀取文字(使用「@」轉義字元)將始終被視為字面量,没有任何特殊含義。這避免了對文字進行任何預處理的需要,只需注意任何最後的換行符號即可。

  echo -n '@ \n 5%' |\
    magick rose: -fill white -stroke black  -font Candice  -pointsize 20 \
            -gravity center    -annotate 0 '@-'   annotate_escapes_file.gif
[IM Output]
換句話說,從檔案讀取時,您不必擔心轉義問題,只需準確寫入您希望 IM 使用的文字即可。

舊版 IM 上的轉義字元

上述定義僅在 IM 6.3.3 版中才最終確定。在此之前,轉義字元有時會在某些選項中處理,有時則不會處理,具體取決於 IM 使用者發送的任何請求、問題和投訴。關於「標籤:」和「標題:」的百分比轉義字元,情況尤其如此,有一段時間被認為是「不合理的」。例如,您是否在以下標籤影像中看到「%c」很大程度上取決於版本(至少在 IM v6.3.3 之前)。

  magick -background lightblue -fill blue -font Candice -pointsize 48 \
          label:'ab%cde'    label_percent.gif
[IM Output]
您是否看到「abde」(已套用百分比轉義字元)或「ab%cde」(未套用百分比轉義字元)取決於您使用的 IM 版本。
IM v6.2.4 中,從「標籤:」和「標題:」中刪除了百分比轉義字元,因為它們不合理。

但是,它們在 IM v6.3.2 中作為新的「%[fx:...]」構造返回,它可以參考任何影像,使文字到影像產生器中的百分比轉義字元再次變得有用。請參閱FX 表達式轉義字元
這個「什麼被轉義」的問題也出現在檔案轉義字元的處理上。在 IM v6.3.3 之前,以下內容會產生兩行,而不是一行。

  echo -n ' Love \n/ Hate ' |\
    magick -background lightblue -fill blue -font Ravie -pointsize 18 \
            label:@-    label_escapes_file.gif
[IM Output]
由於轉義字元處理的結果因版本而異,在 v6.3.3 之前的 IM 中,我建議腳本測試其轉義字元處理,如果它對程式的正確運作很重要,則需進行調整。*如果有人想為 IM 腳本建立自動測試,請貢獻。或者,如果您找到這樣的測試,請告知我。*

Pango - 基本格式化文字

pango:」文字編碼器(從 IM v6.7.6-3 開始完全正常運作)的工作方式與 標籤標題 編碼器非常類似。它在安裝了「Pango」的系統上提供一種有限的文字格式化語言。在 Linux 和 MacOSX 系統上,Pango 是標準配備,在 Windows 上則是可選的。以下是不使用任何特殊 Pango 格式化的簡單範例...

  magick -background lightblue pango:"Anthony Thyssen" pango.gif
[IM Output]
但是您應該注意,某些先前的 文字屬性 不適用於 Pango,這基本上是由於其文字格式化要求。例如,雖然您可以設定「-background」顏色,但您無法設定預設的填充顏色或底色,也無法設定要使用的特定字體。這是因為這些屬性可以透過 Pango 標記語言來選擇(見下文)。建議您使用「-size」來定義輸出影像的寬度和高度限制,Pango 會自動將輸入文字進行自動換行(或針對中文進行自動斷字)。

  magick -background lightblue -size 150 \
          pango:"Anthony Thyssen is the main author of IM Examples" \
          pango_size.gif
[IM Output]
您甚至可以使用 定義、「pango:justify」讓 Pango 正確地「對齊」文字...

  magick -background lightblue -size 150  -define pango:justify=true \
          pango:"Contributions to IM Examples are welcome via the IM Forum." \
          pango_justify.gif
[IM Output]
但請注意,雖然文字可以對齊,但文字格式化時仍會考慮空格和換行符號。此外,Pango 也能理解 TAB 的使用(與標籤和標題不同)。

  printf "col1\tcol2\nabc\txyz\n123\t789" |\
     magick -background lightblue  pango:@-  pango_tabs.gif
[IM Output]
請注意,雖然上述的「printf」命令可以使用「\t」轉義字元產生定位字元,但 IM 並不理解這種轉義字元的使用。不過,它可以理解字串中的「\n」轉義序列。
然而,使用 TAB 產生欄位的效果並不好,因為您無法輕鬆地在 API 之外定義「定位點」。因此,*不建議*以這種方式使用 TAB,除非是用於行和段落縮排。

Pango 標記語言

然而,Pango 的真正強大之處在於「Pango 標記」語言,預設情況下會啟用該語言。您可以使用「-define pango:markup=false」關閉 Pango 標記,但這樣您也可以改用 標題。「Pango 標記」與 HTML 非常相似,您可以在文字中使用一組「<...>」標記標籤,這些標籤用於控制文字的格式化方式。以下是一些關於標記語言的指南(不含 API 垃圾)例如..

  magick -background lightblue -gravity center -size 180x \
          pango:"The <b>bold</b> and <i>beautiful</i>" \
          pango_formatting.gif
[IM Output]
<span ... >」標籤是 Pango 標記中使用的主要標籤。它允許您精確控制所含文字的大小、顏色和位置。例如..

  magick -background lightblue \
       pango:'  Some  <span size="49152" rise="-20480"
                foreground="red" background="blue"
                 > Big Red on Blue </span>  Text  ' \
       pango_span.gif
[IM Output]
請注意,大多數數值都乘以 1024 作為因子,因此上述範例中「size="49152"」的值表示文字點大小為 48 點。而負上升值(「rise="-20480"」)表示將文字位置降低 20 點(或 72dpi 的像素)。但是,除了為文字指定點大小之外,我也可以使用特殊的尺寸標籤,例如「size="x-large"」。請參閱下一個範例的原始碼。請注意上述引號中的引號。標籤內的引號是必需的。但是,標籤內的換行符號和額外空格不會參與文字格式化。因此,在標記標籤或標記註釋「<!-- ... -->」中隱藏額外的換行符號非常有用。再次查看下一個範例的原始文字。作為 pango 格式化功能的最後一個範例,我在這裡使用它來格式化預先準備好的檔案「pango_test.txt」。這包含您可能會使用的大多數常見 pango 標記標籤。將此標記檔案與下面的結果圖像進行比較。

  magick -gravity center pango:@pango_test.txt  pango_test.png
[IM Output]

Pango 筆記和問題

重力
我無法讓 pango 選擇性地僅將單行文字置中。您只能透過「-gravity」設定將所有內容置中或不置中。造成這種情況的原因似乎是因為 pango 設計用於為應用程式生成單獨的文字標籤。也就是說,標題通常與顯示文字的主體分開生成。Pango 並不意味著成為一個完整的文字頁面格式化引擎。
字體
Pango 可以在渲染過程中更改字體。它已經可以輕鬆地處理粗體和斜體文字。但是,字體規範來自 GTK,因此與 ImageMagick 使用不同的系統。您可以透過執行「gtk-demo」程式,然後雙擊「選擇器」和「文字小工具」來進一步了解使用 GTK 的字體。
定義
有很多特殊的 定義 可用於全局控制 pango 文字格式化的各個方面。這些目前列在 虛擬檔案格式 上,不過我自己並沒有全部探索過。以下是我用過的那些...
-define pango:markup=false
關閉標記語言標籤。然後,任何標籤都包含在輸出中。文字中不可能進行 pango 格式化。這在偵錯時特別有用,可讓您準確查看 pango 看到的輸入內容。
-define pango:justify=true
在圖像大小的寬度內對齊文字。也就是說,添加額外的詞內間距,以便文字塊的左右邊緣對齊。

更多關於 Pango 的資訊

要查看可能的情況,請參閱 Pango Script Gallery 如果您使用 pango 做了一些有趣的事情,請貢獻一份力量。您可以發送郵件給我(地址在頁尾),或將其發佈在 IM 討論區 上。
在安裝了 pango 的系統上,您也可以使用「pango-view」命令來生成 pango 格式的圖像。但是,其預設的「密度」或「dpi」設定是您的顯示器(IM 預設使用 72 dpi),因此可能會因主機而異。

文字 - 純文字頁面

text:」輸入格式設計用於將純文字轉換為由每頁文字組成的一個圖像。它是 ImageMagick 的「分頁文字」輸入運算符。換句話說,它的目的是將較大的預格式化文字檔案轉換為頁面,就像印表機將純文字列印到單獨的紙張上一樣。
不要將「text:」檔案輸入格式與類似的「txt:」輸入格式混淆。後者會先嘗試將檔案讀取為「IM 像素列舉」影像格式。

這並不表示副檔名為「.txt」的純文字檔會失敗。事實上,這樣的檔案可能會如您預期般轉換,因為如果無法辨識列舉的影像,「txt:」檔案格式會自動退回「text:」格式。

然而,以這種方式處理文字有一些問題。首先,文字會被繪製到一個大的畫布上,如果您不想要這些空白區域,則必須移除它們。另一個問題是,文字行不會「自動換行」,而是會超出畫布,如果太長就會被截斷。最後,對於非常長的文字檔,除非採取一些額外的預防措施,否則會產生多頁(影像)。另一方面,「text:」幾乎可以處理任何文字檔,而不會修改產生的最終影像大小,也不會對非常長的文字行進行自動換行。您也不需要像在命令列上使用文字那樣預先處理和特殊字元。最後,更重要的是,如果使用等寬字體(如 Courier),則具有間隔數據欄的檔案在間隔數據欄中仍會保留該數據。基本上,「text:」會將輸入檔案「按原樣」進行轉換。
從檔案讀取的輸入文字數據基本上會直接傳遞給字體程式庫以繪製 UTF 文字。因此,某些控制字元可能會使用不尋常的「字元符號」繪製。這包括TABFORMFEED字元,在撰寫本文時,「freetype」程式庫無法正確處理這些字元。

如果這是一個問題,您可能需要使用過濾器程式(例如「expand」)預先處理您的文字檔,以便將TAB字元轉換為適當數量的空格。
繪製文字時,會以目前的解析度(使用「-density」設定)建立一個大的「字母」大小的頁面(或使用「-page」指定的頁面大小或類型)。根據預設(在 72 dpi 下),它的大小為「612x792」像素,對於大多數用途來說,這個尺寸都很大。例如,以下是將「magick」命令的純文字格式手冊直接轉換為影像的範例(它很大,因此要查看它,請選擇右側的「頁面」影像)...

  man magick | col -b | expand | \
    magick -font CourierNew  text:- -delete 1--1 text_manpage.gif
[IM Output]
然而,上述的手冊到影像的轉換會產生多個頁面(影像),因此我刪除了第二個和後續的頁面,只留下第一個頁面,而不是所有頁面的 GIF 動畫。

我也可以附加一個讀取修飾詞[0]」輸入檔名,例如「text:-'[0]'」,以指示 IM 只讀取產生的第一個影像。不過,目前所有頁面選擇的處理方式仍然是產生所有頁面並刪除不需要的頁面。
我在上面特意使用了「等寬」字體「CourierNew」,以便保留列印頁面中存在的字元間距格式。請注意,此輸出與上述caption:的輸出有何不同。也可以使用下一節Postscript中提供的相同技術來改進此影像的整體外觀。如果您只是想知道「A5」頁面在 100 dpi 下的大小,則可以使用以下命令產生一個該大小的空白頁面,並以像素為單位返回其大小。檔名「/dev/null」是一個特殊的 UNIX 檔案,它始終是空的。

  magick -page A5 -density 100 -units PixelsPerInch  text:/dev/null \
          -format 'Page Size at %x = %w x %h pixels'  info:
[IM Text]

修剪文字頁面

由於文字是被「繪製」在一塊大型畫布上,所以您可能會想要移除所有產生的未使用空間。這可以使用影像操作「-trim」、「+repage」來完成,然後為了讓它看起來合理,可以使用「-border」重新添加一些邊緣空間。當然,您还需要将用作「-bordercolor」重新添加的颜色与您使用的「-background」顏色相匹配。聽起來很複雜?其實不然,例如...

  echo "    Hello Cruel World    " |\
    magick -background  lightblue  -fill blue  -pointsize 18 \
            text:-    -trim +repage  -bordercolor lightblue  -border 3 \
            text_trimmed.gif
[IM Output]
在上面的例子中,「-trim」用於移除「text:」頁面圖像中大量的額外空白。然而,這也會移除一行文字前的任何前導空格!不過,有一個有趣的技巧可以讓您「-trim」圖像到繪製在頁面上的實際文字大小,包括輸入中的任何前導和尾隨空格。這使用了一個特殊的「-undercolor」設置(稍後詳細介紹)。

  echo "    Hello Cruel World    " |\
    magick -background  white -undercolor lightblue  -fill blue \
            -pointsize 18   text:-  -trim +repage \
            -bordercolor white  -border 3    text_boxed.gif
[IM Output]
文字底部多餘的空間是由於文字輸入中最後一個「換行」字元造成的,它在圖像中產生了一個額外的空白行。但正如您所見,輸入文字的前導和尾隨空格被保留了。如果您在上面使用透明背景顏色,則可以將修剪後的圖像扁平化,將未繪製的區域變成與使用的「底色」相同的顏色。

  echo "    Hello Cruel World    " |\
    magick -background  none  -undercolor lightblue  -fill blue \
            -pointsize 18   text:-  -trim +repage  \
            -bordercolor lightblue  -border 3 \
            -background lightblue  -flatten    text_box_trimmed.gif
[IM Output]
上述結果(除了添加的「-border」之外)實際上幾乎與 IM 現在使用「label:」並從「@」轉義檔名讀取的結果完全相同。但是,「label:」以更快、更簡潔的方式完成(通過「freetype」函式庫而不是 PostScript 轉換)。您可以指定一個較小的「-page」大小,可以使用像素(請參閱下一個示例)或使用媒體頁面大小(例如「A5」),並使用「-density」或像素解析度設置。您還可以指定開始在頁面上繪製文字的偏移量,該偏移量相對於左上角。例如...

  echo "This is a long line that shows that 'text:' does not word wrap." |\
     magick -background  lightblue  -pointsize 18 \
             -fill blue  -page 320x95+50+10  text:-'[0]' +repage  text_page.gif
[IM Output]
幾乎所有其他圖像創建運算符都使用「-page」設置來設置更大的虛擬「畫布」和畫布上圖像的「偏移量」,通常用於圖層圖像或生成動畫。因此,在任何「text:」或「ps:」操作之後,最好使用「+page」重置頁面設置,否則您可能會在同一命令行上讀取的任何輔助圖像中得到意外結果。

這也是我在上面的例子中添加「+repage」運算符的原因,否則文字會偏移,生成的圖像也會偏移!

有關使用此偏移量的更多詳細信息,請參閱頁面圖像屬性
請注意,在最後一個範例中,任何過長的文字行如果超過頁面寬度,將會溢出頁面,而且不會「自動換行」。這實際上會裁剪並捨棄行尾的文字。此外,如果行數過多,「text:」將會產生「多頁」,進而產生「多個影像」,每個影像對應於 PostScript 轉譯文字檔後產生的每一頁。如果您只對第一頁文字感興趣,或者只是想避免產生多個影像,請在「text:」檔名後面加上「[0]」,以指示 IM 只讀取文字轉換成影像「後」產生的第一頁(請參閱前面的範例)。

Postscript/PDF - 預先格式化的文字和圖形輸入
(或其他向量影像格式)

以下提供一種標準向量影像處理技巧,不僅可用於「PS:」(PostScript)影像,也可用於使用向量圖形處理的所有其他影像。這包括以下影像格式:「PDF:」(可攜式文件格式)、「TEXT:」(分頁純文字),甚至「SVG:」(可縮放向量圖形)和「WMF:」。您可以擴展此方法,精確控制文字轉換成影像後的顯示方式。例如,使用正確的「文字轉 PostScript」篩選器,您可以控制 PostScript 影像中的自動換行、對齊、多重字型處理、粗體、框線、標題、檔名、日期和其他裝飾。但是,由於本節討論的是文字轉影像,這表示您需要先將文字轉換成格式化的 PostScript 檔案。您可以使用許多外部程式來執行此操作。例如,「a2ps」、「enscript」或「pstext」。基本上,您可以使用文字處理器(如「OpenOffice」或「Word」,甚至「Notepad」),或者,如果您需要批次文字處理系統,可以使用「TeX」和「LaTeX」來產生預先格式化的文字(請參閱下面的「完整的文字處理系統」)。這些程式都設計用於處理混合純文字、粗體、不同大小和字型的文字,以及自動換行、對齊和段落控制。然後,您可以將這些程式的輸出傳遞給 IM,將其轉換成您需要的大小和品質的影像。因此,讓我們先產生一些 PostScript(將文字從個人命理程式轉換而來)。

  mesgs LN-ManKzinWars | \
    a2ps -q -1 --rows=10 --prologue=bold \
         --center-title="Postscript via 'a2ps'" \
         --header='' --left-footer='' --right-footer='' \
         -o ps_version.ps
[IM Output]
現在,我們可以將其轉換成影像,並修剪結果(如同上面的「text:」範例),以移除預設頁面/畫布產生的多餘空白區域。

  magick ps_version.ps'[0]' \
          -trim +repage   -bordercolor white -border 3  ps_version_raw.gif
[IM Output]
請注意,這裡使用「[0]」將輸入限制為僅第一頁。如果您的 PostScript 影像產生多頁,「ghostscript」代理程式仍然會完整處理,但 IM 只會讀取傳回的第一個影像,而不是產生多個影像(每頁一個影像)。如果您的 PostScript 檔案非常大,您可能需要使用其他 PostScript 工具程式來限制頁數,然後再使用 IM 和「ghostscript」進行處理。如您所見,轉換成預設「-density」(解析度)72 dpi 的 PostScript 通常看起來不如預期,只有極少的消除鋸齒效果。在處理 PostScript 字型時尤其如此,因為這些字型並非設計用於這種低解析度。為了改善這一點,您可以使用「超級採樣」技術來產生更好的影像。在這種情況下,您可以要求「ghostscript」以更高的解析度繪製頁面(或影像「-density」)。然後,您可以「-resample」(一種「特殊的調整大小」操作)將這個較大的影像縮小到更「正常」的螢幕解析度。

  magick -density 196   ps_version.ps'[0]' -resample 72 \
          -trim +repage   -bordercolor white -border 3  ps_version.gif
[IM Output]
數值 '196' 是最終 72dpi 的 3 倍,這意味著當使用 "-resample" 時,大約 3×3 個像素會合併成一個像素。這會在文字邊緣產生更好的反鋸齒像素,從而改善結果的整體外觀。另請注意,使用較大的密度或解析度與僅放大字體並不完全相同。字體定義可以進行調整以處理低解析度情況。例如,比較兩個圖像中字母 'e' 中的孔洞。由於字體內的特殊處理,原始版本更清晰,即使後者的超級採樣版本總體上更清晰。如需更多信息,請參閱下面的解析度、點大小和實際字體大小。您不必使用上面的值,因為有時稍微不同的值可能會產生更好或更理想的結果。當然,讓 "ghostscript" 生成大 2 倍、3 倍甚至 4 倍的圖像也意味著 IM 將花費 4 倍、9 倍或 16 倍的時間來生成圖像!它還會使用更多內存和臨時磁盤空間!但結果通常是值得的。最好的辦法是針對您自己的文檔進行嘗試,看看哪種方法可以獲得最佳結果。此外,如果您需要更多反鋸齒,而不是使用更大的輸入解析度,您可以嘗試在縮小圖像大小之前將其模糊亞像素量(例如 '-blur 0x0.7')。我有時還發現,調整大小後進行非常少量的銳化(一種常見的 Photoshop 技術)可以改善整體最終結果。

  magick -density 196   ps_version.ps'[0]' \
          -blur 0x0.7 -resample 72 -unsharp 0x0.7 \
          -trim +repage   -bordercolor white -border 3  ps_unsharp.gif
[IM Output]
但我會小心這些調整,因為它可能會使事情變得更糟。
如果您希望背景透明而不是白色,則可以指定 'RGBA' 的 "-channel" 設置,以便在圖像中包含 Alpha 色板。當然,您需要使用可以處理半透明顏色的圖像格式。

  magick -channel RGBA -density 196  ps_version.ps'[0]' -resample 72 \
          -trim +repage   -bordercolor none -border 3  ps_transparent.png
[IM Output]
請注意,橫幅仍然使用灰白色作為其背景,而不是也使其透明或半透明。這是因為生成的 PostScript 實際上繪製了該背景,替換了頁面的默認背景(無論是白色還是透明)。像這樣使背景透明將允許您將 PostScript 圖像覆蓋在特定背景顏色上。

  magick ps_transparent.png -background skyblue -flatten  ps_bgnd_color.gif
[IM Output]
使用Alpha 合成方法,您甚至可以將其覆蓋到特定背景圖像或平鋪背景上。

  magick composite -tile bg.gif  ps_transparent.png  -compose DstOver \
            ps_bgnd_tiled.gif
[IM Output]
由於幾乎所有 PostScript 打印機只能使紙張或透明膠片變暗(這包括彩色打印機),因此在打印上述內容時,橫幅會自動變為半透明。如果您還希望 IM 做同樣的事情,就像打印機那樣,您可以使用特殊的 'Multiply' Alpha 合成,將“白色背景”圖像覆蓋到所需的“紙張”背景上。

  magick composite -tile bg.gif  ps_version.gif  -compose Multiply  ps_multiply.gif
[IM Output]
如果您有彩色 PostScript 圖像,您還可以通過使用特殊的 'BumpMap' 合成方法在彩色紙張上模擬純黑白打印機。這將在使用乘法將圖像合成在一起之前將源疊加圖像灰度化。您還可以生成相當於透明膠片幻燈片的灰度圖像。這基本上使用不透明的白色背景圖像(來自上方)作為“遮罩”,使用Alpha 形狀運算符設置形狀透明圖像

  magick ps_version.gif -negate -background black -alpha shape  ps_overhead.png
[IM Output]
與上面的 "text:" 轉換器一樣, "ps:" 轉換器也使用 "-page" 設置來設置在其上繪製頁面的圖像“介質”的畫布大小。雖然提供的偏移量將被忽略。但是,由於大多數 PostScript 文件在內部定義了繪圖介質大小,因此通常不需要這樣做。
大多數其他的圖像創建運算符使用「-page」設定來設定「虛擬畫布」和該虛擬畫布上的偏移量(例如,用於生成 GIF 動畫)。 因此,在將其用於「text:」或「ps:」圖像讀取操作後,最好使用「+page」將其重置,否則您可能會在後面的圖像中得到意想不到的結果。

有關使用此偏移量的更多詳細信息,請參閱頁面圖像屬性
作為最後一個實際示例,請看一下我的光線追踪四面體圖像。其他類似的圖像可以在多面體研究中看到。背景頁面是使用與生成顯示的 3D 數學對象相同的數據生成的。文本數據使用「a2ps」進行轉換,然後使用 IM 將其轉換為圖像。在此圖像上,將同一數學對象的其他預先準備好的線條圖添加到頁面中。然後將此最終圖像(以“targa”或 TGA 格式保存)傳遞給「PovRay」光線追踪器,以包含在最終圖像或光線追踪場景中。

直接使用 GhostScript

雖然這與 IM 沒有直接關係,但 *Richard Bollinger* 報告說,直接運行「ghostscript」委託的效率要高得多,由於 IM 減少了文件處理,因此處理速度提高了一個數量級。例如,不要運行...

  magick -density 300x300 -compress Group4 file.ps  file.tif
您可以讓 GhostScript 直接執行。

  gs -dBATCH -dNOPAUSE -sDEVICE=tiffg4 -r300x300 \
     -sOutputFile=file.tif  file.ps
這避免了 IM 生成大型臨時文件(為了安全性和管道圖像處理)。因此,直接使用 GhostScript 可以節省大量的文件處理和 IO 處理,並且可以在處理 PostScript 和 PDF 文件時顯著提高性能。但是,「ghostscript」不能調整圖像大小(除了調整輸出密度或分辨率),並且可能無法以您需要的圖像文件格式或您想要的質量輸出圖像。但是,您始終可以將 GhostScript 輸出提供給 ImageMagick 以完成任務。也就是說,如果您想對結果進行超級採樣(更高分辨率的輸入,調整為更小的輸出),則更是如此。GhostScript 可能是一個難以弄清楚如何使用或針對特定類型的 PostScript 進行修復的程序。Cristy 不斷代表 IM 用戶與這些問題作鬥爭,並且在這方面他做出了巨大的努力。不幸的是,在處理可能(並且確實)發生的許多事情時,IM 無法通過 GhostScript 為 PostScript/PDF 提供簡化的方法。

繪製 - 在現有畫布上繪製文本

通過使用低級別的「-draw」運算符繪製字體,我們可以獲得更多控制權,尤其是在字體的確切位置以及繪製字體的圖像大小方面。

  magick -size 320x100 xc:lightblue  -font Candice -pointsize 72 \
          -fill blue  -draw "text 25,65 'Anthony'" text_draw.gif
[IM Output]
但是,要使用它,我們需要生成一個適當大小的背景圖像來繪製字體,這在繪製一些未知文本時可能會很棘手。有關解決此問題的方法,請參閱字體圖像的自動調整大小。除了標準文本選項之外,還有許多額外選項也會影響「-draw」實際在圖像上繪製文本的方式。您不僅可以指定「-fill」顏色,還可以指定「-undercolor」以及邊緣或「-stroke」顏色,這兩種顏色默認情況下都是關閉的(設置為顏色「none」)。「-fill」顏色也可以替換為「-tile」圖像樣式,而筆劃邊緣寬度可以使用「-strokewidth」更改。然後可以使用「-gravity」設置更改繪製文本的相對位置。例如,我在這裡使用了許多我剛才提到的額外功能。

  magick -size 320x100 xc:lightblue  -font Candice -pointsize 72 \
          -tile bg.gif  -undercolor dodgerblue  -stroke navy  -strokewidth 2 \
          -gravity center  -draw "text 0,0 'Anthony'" text_options.gif
[IM Output]
從 IM 版本 6.2.4 開始,「-draw text」操作不再理解使用「\n」作為換行符,也不再理解使用百分比「%」圖像信息轉義。(請參閱繪製百分比錯誤)。

但是,這些功能和問題在新 IM v6 運算符「-annotate」中仍然可用。請參閱下面的註釋文本繪製運算符
以上所有選項也可以在「-draw」(MVG - Magick Vector Graphic)字符串中使用。但是,如果您在 draw 參數中設置了上述選項,則該選項將僅適用於該特定的 draw MVG 字符串。最重要的是,draw MVG 格式可以做更多的事情,例如文本旋轉和字體「裝飾」,當然您也可以在圖像上繪製各種形狀,如圓形。例如,我們在這裡繪製了帶下劃線的旋轉文本,覆蓋在幾個背景圓圈上。

  magick -size 320x120 xc:lightblue \
          -draw "fill tomato  circle 250,30 310,30 \
                 fill limegreen  circle 55,75 15,80 \
                 font Candice  font-size 72  decorate UnderLine \
                 fill dodgerblue  stroke navy  stroke-width 2 \
                 translate 10,110 rotate -15 text 0,0 ' Anthony '" \
          draw_mvg.gif
[IM Output]
如果您真的想最大限度地利用「-draw」來創建圖像,我建議您查看繪圖示例頁面

底色框

如上所述和後文所示,「-undercolor」顏色設置將為該字符和字體的定義繪製區域著色。通常,它只適合繪製的字符。繪製字體的左右邊緣尤其如此,因為頂部和底部邊緣通常足夠大以容納所有字符。繪製區域基本上代表了繪製字體區域周圍的字符「單元格」邊界。使用「-undercolor」選項的主要用途是一種簡單快捷的方法,可以清除文本周圍的「嘈雜」背景。例如,請查看在頂部圖像上註釋。但是,建議您在這種情況下在要繪製的字符串的開頭和結尾添加一個額外的空格字符。

邊界框溢出

在繪製文字,或是一般處理字體時,您可能會遇到的最大問題之一,就是並非所有字體都遵守一般規則。字體設計師可以將個別字元(或「字形」)「繪製」在相對於目前文字位置(稱為插入號)的任何位置。字體位置甚至不需要向前移動,在某些國際字體中,甚至可能向後移動!這種設計自由度的結果是,某些「字形」不符合字體宣告字元適合的定義繪製區域,尤其是在傾斜或草寫字體中,字母的某些部分會超出邊界,並進入稍後(或先前)字元使用的區域。在這方面,我看過最糟糕的字體是「LokiCola」字體,它繪製大約一半的大寫字母,並帶有長長的波浪形尾巴,遠遠超出個別字元方格的邊界。該字體基本上假設每個大寫字母後面都會跟著 3 個或更多個小寫字母。為了說明這一點,我將分別繪製該字體的一些大寫字母,讓您可以看到這些字母可能會超出方格「底色」或繪製邊界的範圍。我也會使用其中幾個字母來組成字體名稱,這樣您就可以看到它們設計用於何處,以及為什麼它們會溢出邊界框。

  magick -size 500x200  xc:lightblue \
          -font LokiCola  -pointsize 72  -undercolor dodgerblue \
          -draw "text  15,65 'L'"   -draw "text 130,65 'C'" \
          -draw "text 245,65 '1'"   -draw "text 360,65 'H'" \
          -gravity South -draw "text 0,10 'Loki Cola'"    draw_undercolor.gif
[IM Output]
另請注意「H」實際上是如何在其繪製區域的左側和右側溢出的。這可能會導致難以在行首使用它。
請記住,這個問題不是 IM 中的錯誤,而是由 IM 使用的字體庫和字體本身的設定互動造成的,通常是字體設計師故意為之。IM 只是按字體中的程式設計使用結果,這並不總是產生使用者預期的結果。因此,建議謹慎使用不尋常的字體。

註釋 - 文字繪製運算子

在 IM 版本 6 中,提供了一個新的字體繪製運算子「-annotate」。這個運算子在許多方面比使用「-draw 文字」操作更簡單,但由於它使用「annotate()」API(應用程式介面),因此也更加強大。雖然該運算子確實使用了「-draw」基元,但它的方式更為複雜,例如展開特殊跳脫字元以新增額外的影像資訊,甚至多行,並對繪製的文字套用座標系轉換以產生傾斜和旋轉。因此,該運算子現在是所有 ImageMagick 文字繪製和影像註釋的首選文字繪製運算子,這一點現在反映在這些範例頁面中。以下是使用此運算子的基本範例。

  magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
          -fill blue  -annotate +25+70 'Anthony'    annotate.gif
[IM Output]
-annotate」運算子的額外功能之一是,它可以完全獨立地旋轉繪製文字的 X 軸和 Y 軸。這是透過在運算子引數中提供每個軸旋轉的角度作為「影像大小」來完成的。為了說明單個「-annotate」操作可以有多複雜,以下是一個帶框、描邊和傾斜的影像...

  magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
          -tile bg.gif  -undercolor dodgerblue   -stroke navy -strokewidth 2 \
          -annotate 0x20+20+67 'Anthony' annotate_opts.gif
[IM Output]
在本範例中,給出了所有四個註釋參數。具體來說,是 X 軸旋轉、Y 軸旋轉,以及背景影像上字型的 X 和 Y 位置。另請注意,填充圖樣(使用「-tile」設定)也會隨著字型傾斜。這是因為它是使用剪切/旋轉的座標系統繪製的,該系統也會剪切並填充繪製文字中的圖樣。此剪切功能的更多範例,請參閱剪切陰影字型範例。將其與使用等效「-draw」MVG 字串建立的傾斜字型進行比較。如需總結「-annotate」剪切操作效果的表格,請參閱註釋參數用法。例如,以下是一些稍微旋轉的文字…

  magick -size 320x100 xc:lightblue -font Candice -pointsize 72 \
          -annotate 350x350+20+90 'Anthony' annotate_rotated.gif
[IM Output]
請注意,提供給「-annotate」的角度必須為正數,IM 才能正確理解。唯一的例外是,如果使用以逗號分隔的 4 個數字形式的幾何參數。例如,最後一個範例中可以使用「-annotate '-10,-10,20,90' 'Anthony'」。
這可以用於產生傾斜的壓縮標籤。例如…

  magick -size 100x60 xc:skyblue \
          -annotate 300x300+20+50 "First" \
          -annotate 300x300+35+50 "Second" \
          -annotate 300x300+50+50 "Third" \
          -annotate 300x300+65+50 "Fourth" \
          -annotate 300x300+80+50 "Fifth" \
          annotated_labels.jpg
[IM Output]
您也可以使用跳脫字元,將有關目前影像的其他資訊新增至註釋字串。例如,讓我們使用有關影像大小的資訊覆蓋內建的「rose:」影像。為了將文字置中於影像上,我們使用「-gravity」設定,並使用「-annotate」參數「0」來關閉任何和所有旋轉和偏移。

  magick rose: -fill white -stroke black  -font Candice -pointsize 20 \
          -gravity center   -annotate 0 '%wx%h\nPixels'    annotate_rose.gif
[IM Output]
如需更多資訊,請參閱下方的文字參數中的特殊跳脫字元。如需以各種方式將文字註釋到較大影像的其他範例(例如置中於側面或旋轉於右下角),請參閱實用的文字註釋範例

自動調整大小的註釋文字畫布

通常,您需要比「label:」所能提供的更多控制。例如,您想要使用平鋪或漸層影像,這需要您註釋文字。可惜的是,您需要事先知道註釋文字所需的畫布大小。以下是一個典型的問題範例。當我第一次設定此命令時,我將大小設定為我想要的結果,一開始它運作良好。但後來我得到了這個…

  magick -size 480x80   gradient:yellow-green \
          -font ArialBkI -pointsize 70 -tile gradient:blue-red \
          -annotate +10+65 'Gradient Fun'    funfont_gradients.jpg
[IM Output]
可惜的是,在猜測畫布大小時,我在上面的「Gradient」一詞中拼錯了字(缺少字母「i」)。當然,當我修正拼寫後,我的影像大小現在不正確了,產生了上面顯示的不正確結果。我們需要的是能夠使用「-annotate」運算子,但畫布大小要適合註釋文字。一種解決方案是使用更大的畫布,然後「裁剪」背景到正確的大小。我還新增了「邊框」,以便在字型和影像的最終邊緣周圍新增一些額外空間,以獲得更好的外觀。

  magick -size 800x120 xc:black -font Corsiva -pointsize 100 \
          -tile tile_disks.jpg   -annotate +20+80 'Psychedelic!' \
          -trim +repage  -bordercolor black  -border 10   funfont_groovy.jpg
[IM Output]
這種方法比試圖猜測最終影像的大小要好得多,但是「畫布裁剪」不會裁剪平鋪的多色背景。更好的解決方案是使用「label:」建立畫布,以產生正確大小的畫布。然後使用繪製顏色填充將影像平鋪在畫布(和標籤文字)上,最後我們使用另一個平鋪影像註釋我們的文字。

  magick -font Ravie -pointsize 72  label:'Get Wet!' -border 10 \
          -tile tile_aqua.jpg   -draw "color 0,0 reset"  \
          -tile tile_water.jpg -gravity center -annotate +0+0 'Get Wet!' \
          autosize_wet.jpg
[IM Output]
請注意,在置中的「label:」影像中,文字的位置可能與置中的「-annotate」操作的位置不完全相符。這兩種方法遵循完全不同的處理演算法,因此可能無法匹配。特別是在涉及特殊字體時。

使用「底色方塊」自動調整大小

您可以不使用「label:」影像,而是在一個大的畫布上使用底色方塊較大的筆劃寬度繪製字體,然後再將畫布修剪至合適的大小。例如

  magick -size 500x100 xc:lightblue -font SheerBeauty -pointsize 72 \
     -gravity center -undercolor white -stroke none -strokewidth 3 \
     -annotate +0+0 ' Invitation ' -trim +repage -shave 1x1 \
     invitation_box.jpg
[IM Output]
可以使用「-strokewidth」設定調整字體周圍的間距。唯一的要求是初始畫布的顏色必須與背景顏色不同(在本例中為「lightblue」),並且必須大於最終結果。提醒您,有些字體會在個別字元繪製區域之外繪製字元。(例如,請參閱上面的底色方塊)。在這種情況下,上述結果將會有效,但可能需要您使用透明畫布,然後將結果覆蓋在白色上(例如,使用「-background white -flatten」之類的操作),將未使用且仍然透明的區域變成白色。但是,該字元可能會碰到結果影像的邊緣。基本上,您不可能在所有情況下都贏,盡力而為即可。

為灰階文字圖像上色

我特意將上面的影像生成為灰階黑白影像,因為這可以用作遮罩範本。從這樣的純影像中,您可以分別或同時為影像的背景和前景上色。例如,我在這裡使用依顏色分級運算子+level-color」,以全局方式修改影像顏色,以便為前景和背景顏色分配特定值。

  magick invitation_box.jpg -colorspace sRGB \
          +level-colors navy,lightblue invitation_colored.jpg
[IM Output]
例如,我在這裡使用合成遮罩來用圖案影像替換背景和前景。

  magick invitation_box.jpg -colorspace sRGB \
          \( +clone -size 300x150 -tile gradient:LightYellow \
                                             -draw "color 0,0 reset" \) \
          \( +clone -size 300x150 -tile plasma:tomato \
                                             -draw "color 0,0 reset" \) \
          -reverse  -composite      invitation_rose.jpg
[IM Output]
上面使用反轉運算子來重新排序影像,因此第一個影像成為合成的第三個「遮罩」影像。然後,前景(「plasma:」)影像成為第一個影像,背景影像在中間。如需為此類灰階影像上色的其他技術,請參閱使用遮罩限制合成區域。更一般地說,請參閱在影像中使用遮罩。如需用於平鋪的漸層生成的其他方法,請參閱顏色漸層稀疏顏色點隨機畫布

字體

建構中
As for ordering the font paths, that is simply ordering the fonts specified in
the XML files.

The start point is the system fonts, followed by the system installed
"type.xml" file, on my system this is "/etc/ImageMagick-6/type.xml".

This system installed "type.xml" file is typically just a list of 'include'
other type-* files.  And the order of the includes will specify the order of
Extra System Fonts, verses Ghostscript Fonts.

After that file other "type.xml" files are looked for, such as in 'home'
directories, or even current directory.

Later fonts will NOT replace earlier fonts, as such if two fonts have that
same name, only the first one will be noted by IM. (a security measure).

To see the fonts loaded use
    magick -list font

It lists "Path:" of the type file each font list was found in, but the
paths are listed in REVERSE order, with system fonts at the end.

I have for example a personal Font named "Courier", but it is not listed in
the above list as it was defined after the "Courier" that was found in the
"System Fonts" area, (which is listed at the end of the above output).

On the other hand my own personal font "CourierNew", is listed, as it does not
clash with any system or system config defined font.

To see what font glyph file is selected for soem specific request
use...
  magick -debug annotate xc: -font Courier \
          -annotate 0 'Test' null: 2>&1 |
    grep '^ *Font '

確定字體度量,無需使用 API

[圖表]一種特定字體及其個別字元包含許多資訊。這些資訊可能非常有用,特別是當您想要使用 IM 將許多不同字體的文字拼湊在一起時。同樣重要的是要記住,大多數字體都是比例字體,這意味著每個單獨的字元將具有不同的寬度,以及插入符號(或原點)的不同「自然」前進。因此,每個特定的字元「字串」將以不同的長度呈現(繪製),而無需真正考慮字串中使用的實際字元數。此規則的例外是「等寬」字體,例如「Courier」、「Typewriter」或「Terminal」字體,其中所有字元都具有相同的寬度,允許您輕鬆生成文字列。偵錯設定-debug annotate」可用於讓 IM 直接報告 TTF 字體的度量,用於特定字串。舉例來說…

  magick -debug annotate  xc: -font Candice -pointsize 24 \
          -annotate 0 'Test' null: 2>&1 |\
    grep Metrics: | fmt -w80
[IM Text]
如您所見,您可以獲得可使用的混合資訊:從繪製字串的聲明邊界(不一定是字串的實際邊界),相對於原點;到繪製下一個字串之前「插入符號」(原點)應前進的量。完整的偵錯輸出(相當冗長,上面未顯示)還會報告所使用的實際字體檔(兩次),因此您也可以使用它來檢查您是否也擁有正確的字體。
-debug annotate」方法已添加到 IM v6.3.9-2

舊技術

但是,此偵錯輸出可能不方便,或者您可能必須處理比此版本更舊的 IM。以下是一些較舊的範例,其中文字實際上以各種方式和顏色繪製,然後從生成的圖像中提取資訊(作為整數)。例如,讓我們找出相對於固定基線的「Ravie」字體的尺寸,以 72 點為單位。
這是我們將要研究的圖像,作為參考。您實際上不需要將其繪製並保存為圖像,因為我們只是提取數據,而不是圖像。此圖像的顏色將被修改,以便我們可以使用「-trim」分別查看白色和黑色部分以提取使用的度量。

  magick -size 100x150 xc:lightblue -font Ravie -pointsize 72 \
          -fill black -undercolor white  -annotate +20+100 'A' font_drawn.gif
[IM Output]
對於基本的字體度量,我們首先使用透明顏色(「None」)繪製字體本身,以便我們可以測量找到此特定字元在此字體的邊界框或繪圖區域的大小和位置。請注意,對於高度資訊,您可以繪製任何內容。

  magick -size 100x150 xc:lightblue -font Ravie -pointsize 72 \
          -fill none -undercolor white  -annotate +20+100 'A' -trim  info:
[IM Text]
從上面的結果我們可以看到,72 點的「Ravie」字體的總邊界框高度為 74 像素。盒子的頂部距離圖像頂部 42 像素,因為基線位於 y 坐標 100 像素處,盒子開始於基線上方 100 - 42 或 58 像素處。這為基線下方的邊界框留下了 74 - 58 或 16 個像素,用於下行符。
請注意,並非所有字體都將其繪圖限制在其定義的繪圖邊界框內!但是,有些字母可以延伸到這些邊界之外。這就是為什麼上面的例子設置了「-fill」的顏色為「none」。這樣,行為不端的字體不會影響上述測量。
另請注意,行與行之間的距離(實際上是基準線)應該完全由字體的磅值決定,與字體的繪製方式無關。在我們的範例中,由於字體的磅值為 72 點,而一點定義為 1/72 英吋,因此基準線應相距 1 英吋。如果目前的輸出解析度(密度)為每英吋 72 像素,則表示基準線將相距 72 像素。有趣的是,這表示對於此字體,由於其邊界框為 74 像素,因此在正確的單倍行距文字行之間,字體的繪製區域會有 2 像素的重疊!同樣從上述測量結果中,我們可以看到,以這個磅值繪製字串「A」時,下一個字元應該繪製在起點(稱為插入點)右側 66 像素處。這是字串的「邏輯」長度。也就是說,下一個字元的「插入點」或起點應該從 20 + 66 或「+86+100」開始(基準線在垂直方向上不變)。請注意,某些阿拉伯文字體實際上可以從右到左繪製,因此「插入點」偏移量將為負數。這給出了字元「A」的字體度量值,但是繪製的「A」相對於「插入點」或起點的實際尺寸呢?只要交換兩種顏色設定即可...

  magick -size 100x150 xc:lightblue -font Ravie -pointsize 72 \
          -fill black -undercolor none  -annotate +20+100 'A'  -trim   info:
[IM Text]
在高度方面,字元在其定義的繪製邊界內,其高度從基準線上方 100 - 43 或 57 像素(緊貼其邊界框)到字體基準線下方 60 - 57 或僅 3 像素。換句話說,這個字母在基準線下方的繪製區域沒有「下延部」。從這裡我們可以看到,「A」從插入點(位於 +20,但最終圖像位於 +17)*之前* 3 個像素處繪製到插入點位置之後 70 - 3 或 67 個像素處。換句話說,這種字體繪製時比其水平邊界框略寬。請注意,雖然這給出了實際繪製的字串長度,但这與附加文字時所需的插入點偏移量不同(插入點偏移量由字串邊界框定義,而不是由其繪製長度定義)。換句話說,文字應該使用其邊界框附加在一起,而不是像我們在其他範例中所做的那樣使用其實際繪製長度大小。當然,如果您遇到行為非常異常的字體,您可能希望檢查特定字串超出其邊界的繪製距離,以便您仍然可以為其提供空間,例如在行尾。
從字體中提取的尺寸也會隨著用於繪製字體的當前「-strokewidth」而有所不同。如果增加輪廓筆劃的大小,則繪製字體所需的尺寸(和邊界框大小)也會擴展相同的大小,以適應較粗的輪廓。
即使在完全相同的字體庫和 IM 版本沒有更改的情況下,尺寸也會因操作系統(類型和版本)以及 IM 在該系統上使用的委託字體繪製庫的版本而異。當可以使用不同的電腦進行文字繪製時,建議謹慎操作,因為即使是相同的字體,結果也可能会有所不同。
如需更多資訊,請參閱文件 TrueType 基礎 (PDF)。這表明即使我上面的一般性結論也可能並非總是正確的,儘管通常情況下是這樣。請注意,以上範例只會傳回以整數像素為單位的尺寸,而字體使用的所有尺寸都是浮點數。事實上,字體是否從整數像素(插入點)起點繪製,可能取決於應用程序,並影響字體的最終外观。

建立混合字體樣式的行

使用多種字體、字型大小和樣式來建立單行文字並不是 IM 真正設計要處理的事情。當您開始考慮文字對齊、自動換行,以及環繞圖片和其他物件等問題時,情況會變得更糟。這類事情是文字處理器、網頁瀏覽器、文件印表機等程式非常擅長處理的,通常是在使用者互動下進行,但很少有程式能在程式控制下做得很好。其中一個例外是「TeX」及其程式系列(請參閱下方的 完整的文字處理系統),因此如果您真的想以圖形方式處理文字,我建議您看看這個程式系列。另一個選擇是看看各種文件「美化」列印程式,例如 HTML 轉換器。您可以使用這些程式將程式產生的文件變成後製指令碼,然後 IM 就可以將其後製處理成您想要的任何影像格式或樣式。「El Supremo」(來自 IM 討論區)在他的 FontMetrics 程式中建立了一個 API 解決方案(使用 C MagickWand API 介面)。這裡是 「FontMetrics」的範例輸出
雖然 IM 命令列不是為「文字處理」而設計的,但这並不代表您不能將其用於此目的。只是這樣做會比較困難。在這裡,我將提供一些混合不同字體和樣式的文字範例,為大家提供一個起點。人們通常會想到的最簡單的解決方案是將「標籤:」影像附加在一起……

  magick -font LokiCola     -pointsize 36  label:'LokiCola ' \
          -font Candice      -pointsize 24  label:'Candice ' \
          -font SheerBeauty  -pointsize 48  label:'SheerBeauty' \
          +append   wp_label_append.jpg
[IM Output]
但是,您可以看到所有影像都垂直對齊到影像頂部,除非您使用類似的字體,否則看起來不會很美觀。或者,您可以使用附加對齊技巧將它們沿底部對齊。

  magick -size 1x50 xc:none +size \
          \( -background white -font LokiCola -pointsize 36 \
             label:'LokiCola ' \
             -clone 0 +swap  -background none -append \) \
          \( -background white -font Candice  -pointsize 24 \
             label:'Candice ' \
             -clone 0 +swap  -background none -append \) \
          \( -background white -font SheerBeauty  -pointsize 48 \
             label:'SheerBeauty' \
             -clone 0 +swap  -background none -append \) \
          -delete 0   -gravity South -crop 0x50+0+0   +append \
          -bordercolor none  -border 1 -trim  +repage \
          -background white -flatten    wp_label_bottom.jpg
[IM Output]
這樣做是在每個標籤的頂部添加了一些額外的填充,並在水平附加它們之前將它們都裁剪為相同的高度。然後,使用簡單的「-trim」和「-flatten」將行的 高度設定為最高標籤的高度,並填充背景。如您所見,這樣做效果更好,但小字體往往會產生類似下標的行為,而不是正確對齊的文字。我們真正需要做的是通過「基準線」對齊所有文字字串,如果沒有更多文字資訊,這將非常困難。這些資訊在程式 API 下很容易獲得,但從命令列獲得則困難得多。前一個範例部分展示了一種方法。但是,可以在不實際收集基準線資訊的情況下,通過基準線對齊文字。雖然「標籤:」文字影像沒有提供任何關於影像基準線的線索,但您可以專門繪製固定基準線的影像。如果沒有 API,您也不能直接找出繪製文字的長度或高度,因此您首先需要使用一個足夠大的畫布,以確保我們不會遺失任何關於文字影像的資訊。然後,為了保留尾隨空格和文字高度,您還必須充分利用文字註釋的(「-undercolor」)功能,並為影像裁剪提供邊界。現在讓我們看看如何從命令列執行此操作。

  magick -size 500x100 xc:none  -fill blue  -draw 'line 15,0 15,99' \
          -undercolor white -fill black \
          \( -clone 0   -font LokiCola    -pointsize 36 \
             -annotate +5+60 'Loki Cola ' \) \
          \( -clone 0   -font Candice     -pointsize 24 \
             -annotate +5+60 'Candice ' \) \
          \( -clone 0   -font SheerBeauty -pointsize 48 \
             -annotate +5+60 'Sheer Beauty' \) \
          -delete 0 -trim +repage  +append \
          -transparent blue  -trim +repage \
          -background white -flatten   wp_draw_baseline.jpg
[IM Output]
如同先前所述,圖像的裁剪分為兩個步驟。首先,在包含垂直藍線的基礎圖像上繪製文字。因此,當我們裁剪文字時,只會裁剪文字圖像的寬度,並將所有文字保持在相同的基線上。將它們附加在一起後,我們現在可以通過使其完全透明來移除藍色構造線。如果您只是生成黑白圖像,更好的方法是只提取一個非藍色通道,這可以確保您確實獲得了所有構造線。然後,第二次裁剪將裁剪頂部和底部,將其縮小到最大的邊界框。最後,將其扁平化為與邊界框相同的顏色,從而消除其在構造線條時的所有痕跡。如您所見,所有文字現在都已正確對齊基線,無論使用何種字體或字體大小。當然,在這些示例中,我只使用了黑白文字。可以使用其他顏色,只要它們不干擾用於文字對齊的構造線和透明背景即可。使用此技術,您現在可以生成混合字體的文字行,並將它們全部垂直附加到更大的文檔中。您還可以發現,完成所有這些工作需要大量工作,而這些工作通常由文字處理器和網路瀏覽器對使用者隱藏起來。如果您確實打算做很多這類事情,我建議您研究我之前提到的替代方案。

表單填寫

您擁有一些標準填寫表單的圖像,並且您想填寫位於已知位置的欄位。因此,您有一個數據文件,例如“text_data.txt”,如下所示...
[IM Text]
這些欄位是文字寬度、重力(對齊方式)、顏色、位置 x、y 以及要為此欄位放置的實際文字。現在,您可以使用一個簡單的循環 shell 腳本來生成如上所述的文字標籤,在表單(背景)圖像中定義的文字位置分配適當的文字。

  cat text_data.txt |
  while read width gravity color  pointsize x y text
  do
    magick -size ${width}x -gravity $gravity -fill $color -background wheat \
                -pointsize $pointsize  -page +${x}+${y}  label:"${text}"  miff:-
  done |
    magick -size 200x100 xc:   -   -flatten    text_layered.jpg
[IM Output]
在這種情況下,“表單圖像”只是一個空白圖像,但實際上可以是任何東西。我還將標籤的背景顏色設置為“小麥色”,以便可以看到填充的區域,但您通常會將其設置為無。以上沒有使用臨時文件,而是使用了 MIFF 格式圖像的管道。這是使用 圖像流格式 的一個示例,其中單個圖像只是簡單地附加在一起,一個接一個地在文件或管道中。這只是一個起點。表單欄位可以來自某些定義文件,而要填寫的文字可以來自數據庫或其他數據源。還可以設置其他屬性,例如要使用的字體、文字旋轉等。您還可以包括寬度和高度,或者如果文字應該使用 標題 而不是 標籤 進行自動換行。另請參閱 地圖中的圖釘,了解此技術的另一個示例,與上述非常相似。

文字處理替代方案

生成完整格式的文字文件和文檔的理想方法是將 ImageMagick 用作更大的圖像和文字處理系統的一部分。
工具 用於...
ImageMagick    圖像批處理和準備
Gimp 用於解決一次性問題的 GUI 圖像編輯
 
LyX GUI 文字處理器,用於生成...
LaTeX 用於文檔和書籍的文字處理器...
TeX 底層文字格式
(在頁面上放置符號和字體)
Metafont TeX 字體生成器
基本上 ImageMagick 可以做很多事情,但这并不意味着它是完成这些事情的最佳工具。 对于较大的文档准备工作,最好将其视为一个更大整体的一部分。 上面给出的各种“TeX”工具通常是大多数 Linux 系统的标准安装,并且可以将文本和图像组合成一个统一的整体。 更重要的是,它将文本保留为文本,并根据您的指定对文本进行适当的格式化,完成几乎所有文字和页面包装以及图像排列的艰苦工作。 但不会在“doc”文件中填充无用的格式垃圾。 您可以完全控制,也可以让它自行做出决定。 它们提供了一种生成任何类型文档的方法,从简单的页面、时事通讯甚至整本书,如果您认真对待文档生成,那么这些工具非常值得一看和学习。
Pango(仅限 Linux 和 MacOSX)也提供了一种替代方案。 它提供了 ImageMagick 中没有的许多文本到图像处理功能。 例如 TAB、对齐、页边距、页眉等等。 它甚至有一种标记语言,允许在文本中间更改字体。
其他解决方案还包括许多文本到 PostScript 转换程序,例如我在上面的 Postscript 处理 中演示的用于生成示例 PostScript 文件的“a2ps”。 这会转换和格式化不同类型的文本文件,具有自动换行、加粗和制表符控制,以及相当不错的页眉、页脚、边框和多页选项。 当然,这是通过 Postscript 或 PDF 中间语言进行的间接图像处理。 另一种方法是使用 SVG 或 ImageMagick 绘图命令 对文本进行布局,但您需要处理布局。 有很多工具可以将文本变成图像,而且大多数工具都可以与 ImageMagick 结合使用,对文本图像进行后处理并将其合并到您的图像中。 这让 ImageMagick 可以专注于它最擅长的图像处理。