星期一, 5月 14, 2012

用 ImageMagick 的 convert 合併圖檔

話說生論文的重點在於你有沒有好看的圖…英文不好、論點不佳、結果很慘,只好靠作圖來加分…是這樣嗎。
使用GMT繪圖時,撰寫的scripts習慣以一張圖為一個檔案,並且直接轉成jpg。 可是在論文編排時,常常需要把幾張圖合成一張,然後在圖中附上a,b,c,d。 以前的做法是用power point編排後再存成ps檔,再由ps檔轉成jpg(此時可設定解析度)。 本來以為這樣的做法,解析度可以保持(事實上解析度是很大…可以過論文排版的檢查),不過實際上圖的解析度並沒有很好。 另外的做法是用gimp處理jpg檔,或是保留ps檔使用coreldraw,可是對於不常用這些軟體的我來說很是麻煩。
由於我一直有在使用ImageMagick,尤其是要執行縮小或製作gif檔時使用convert命令的方法很是方便。 當然強大的ImageMagick如果只是要把很有規則(大小一樣有的沒的)的幾張圖重新排列,並加上(a)(b)(c)(d)應該不難,只是我不會,也一直沒空去了解。最近又要排版了,再用回power point實在品質太差(我標準提高了嗎?)。所以只好花點時間研究ImageMagick,哇~簡值是神奇,只要一個指令就可以搞定。 例如我有四張圖如下:




然後透過下面的指令:
convert \( -page -0-0 \( figure4-a.jpg -page +350+220 -background none -fill black -pointsize 220 label:\(a\) -flatten \) -page -0-0 \( figure4-b.jpg -page +350+220 -background none -fill black -pointsize 220 label:\(b\) -flatten \) -bordercolor black -border 50 +append \) \( -page -0-0 \( figure4-c.jpg -page +350+220 -background none -fill black -pointsize 220 label:\(c\) -flatten \) -page -0-0 \( figure4-d.jpg -page +350+220 -background none -fill black -pointsize 220 label:\(d\) -flatten \) -bordercolor black -border 50 +append \) -append out.jpg
就變成這樣一張圖:

很神奇對不對(我是指我能寫出這天書般的指令),只是上面的指令記不起來的啦,下次也保證看不懂的啦。既然已經花點時間去了解ImageMagick裏convert的用法,也相信下次要用時會忘記,只好寫個簡單的scripts幫助記憶,並且希望可以再下次要用時直接取用。如果你有需要就請隨便用,把你的圖搞壞了別怪我就是了。
convert 可以透過( ) 來優先處理,所以下面的邏輯是先對每一張圖加上(a) (b) (c) (d),用-label給文字,-pointsize給大小,-page給位置。另外,圖要合併時是沒間距的,所以透過-border加個白色外框(由-bordercolor設定白色)。
然後用+append把二張做橫向合併,所以每個橫向的合併要再用一個( )
最後把橫向合份好的結果再用-append用垂向合併。大致上是這個意思
convert   ( (圖1加字) (圖2加字) +append)  ( (圖3加字) (圖4加字) +append ) )  -append  outfigname.jpg

scripts的寫法是當然由最裏面的小圖一路往上拓展,內容如下:

figncols=2
fignrows=2
outfigname=out.jpg
figname[1]=figure4-a.jpg
figname[2]=figure4-b.jpg
figname[3]=figure4-c.jpg
figname[4]=figure4-d.jpg

labelvar[1]="label:\(a\)"
labelvar[2]="label:\(b\)"
labelvar[3]="label:\(c\)"
labelvar[4]="label:\(d\)"
labelvar[5]="label:\(e\)"
labelvar[6]="label:\(f\)"
labelvar[7]="label:\(g\)"
labelvar[8]="label:\(h\)"
labelvar[9]="label:\(i\)"
labelvar[10]="label:\(j\)"
labelvar[11]="label:\(k\)"
labelvar[12]="label:\(l\)"
# ( if rows=3, cols=4, there will have 12 figs)
#          rows
# c    fig1   fig2   fig3
# o    fig4   fig5   fig6
# l    fig7   fig8   fig9
# s    fig10  fig11  fig12
#
#
figtots=`expr $figncols \* $fignrows`
pagevar="-page +350+220"  # label position in pixel
#  下面設定圖與圖中的間隔及顏色,這裏是設黑色,寬度50
bordervar="-bordercolor black -border 50"
pointsize="-pointsize 220"  # font size in pixel
pointvar="$pagevar -background none -fill black $pointsize"
for (( i=1; i<=$figtots; i++ )); do
  a[$i]=`echo " -page -0-0 \( ${figname[$i]} $pointvar ${labelvar[$i]} -flatten \)"`
done
for (( i=1; i<=$fignrows; i++ )); do
    b[$i]=`echo "\("`
  for (( j=1; j<=$figncols; j++ )); do
    k=`expr \( $i \- 1 \) \* $figncols \+ $j `
    b[$i]=`echo "${b[$i]} ${a[$k]}"`
  done
    b[$i]=`echo "${b[$i]} $bordervar +append \)"`
done
c=`echo "convert "`
for (( i=1; i<=$fignrows; i++ )); do
  c=`echo "$c ${b[$i]}"`
done
c=`echo "$c -append $outfigname"`
echo $c
echo "the command above is excuting"
eval $c
echo "done"