ruby-robotの夢

cygwin-ruby,qgisの達人を目指す奮闘記

Rmagickで 複数画像の余白一括crop

PDF等を、ワード等に取り込む時、頁毎のJPGを出力し、ワードに貼り付ける。余白はワードで削除して大きさを揃える。枚数が多くなると大変だ。

まとまった数の頁があれば、あらかじめ、irfanviewで、JPGを一括トリミングしてそれを貼るということをしていた。

これを、自動的にトリミングしたくなった。

rmagickでプログラムを作ってみた。

 

# 複数image の余白を、共通の大きさで切り取る。
print "#{$0}:Use after Unload Virus Buster!"
require "rubygems"
require "rmagick"
require "fileutils"

dir=".";pat="test_*.jpg"
rc=0.12 #余白調査範囲率
lc=250 #点の白判定
c0=0.01 #線の白判定率

Dir.chdir(dir)
odir="trimed";FileUtils.makedirs(odir)

"nfis",nfis=Dir.glob(pat)
imgs=Magick::ImageList.new
nfis.map{|nfi| imgs.read(nfi) }
print "sizes",sizes=imgs.map{|img| [img.columns,img.rows]}
xsizes,ysizes=sizes.transpose
print "xus",xus=xsizes.uniq,jx=(xus.size==1) #jx,jy:サイズの均一性
print "yus",yus=ysizes.uniq,jy=(yus.size==1)
exit unless (jx and jy)
if false
imgchk=[imgs.average] ;sizes=sizes[0,1] #早いが、枚数が多いと、誤差が大きい
else
imgchk=imgs
end

spaces=imgchk.zip(sizes).map{|img,(xsize,ysize)|
xsc=(xsize*rc).to_i;jcs=[*0..xsc];js=[*0..xsize]
ysc=(ysize*rc).to_i;jcs=[*0..ysc];is=[*0..ysize]
print img,xsize,ysize
yw=ysize*c0;xw=xsize*c0
lft=jcs.map{|j|
(is.reject{|i| img.pixel_color(j,i).to_hsla[2]>lc}.size>yw)?1:0 }.index(1)
rgt=jcs.map{|j_| j=xsize-j_
(is.reject{|i| img.pixel_color(j,i).to_hsla[2]>lc}.size>yw)?1:0 }.index(1)
top=jcs.map{|i|
(js.reject{|j| img.pixel_color(j,i).to_hsla[2]>lc}.size>xw)?1:0 }.index(1)
btm=jcs.map{|i_| i=ysize-i_
(js.reject{|j| img.pixel_color(j,i).to_hsla[2]>lc}.size>xw)?1:0 }.index(1)
[lft||=xsc,rgt||=xsc,top||=ysc,btm||=ysc]}
print "spaces",spaces
(lft,rgt,top,btm)=trims=spaces.transpose.map{|lens| lens.min}
#triming #@@@@@@@@@@@@@@@@@@@
print "trims",trims

imgs.zip(nfis).each{|img,nfi| nfo="#{odir}/"+File.basename(nfi)
img_crop=img.crop(lft-1,top-1,xsizes[0]-lft-rgt+2,ysizes[0]-top-btm+2)
img_crop.write(nfo)
}

改良の余地

このプログラム、ファイルが大きく、多くなると、結構時間かかる。

ファルが大きい場合、縮小ファイルを作成して余白を調べる等の改良を行うべきである。

誤差小さくするためには、averageではなく、compositeで、DarkenCompositeOpで合成する。

 複数ファイルの余白は、全部共通ではなく、下余白のみは、個別にの場合もある。