EPS -> ラスタライズされたEPS

大量のデータを基にプロットをして、EPSファイルを作成した場合、高品質ではあるけど数十MBというファイルサイズになってしまうことがあります。このままだと、PDFを作成したり閲覧、印刷するのにとても時間が掛かってしまいます。このような場合には、ベクトル形式のEPS画像をビットマップ形式にラスタライズすることで、品質とサイズのトレードオフを調整するのが有効です。


僕の場合、最初は EPS -> PNG -> EPS と、PNG形式を経由してラスタライズすることを考えました。
EPS -> PNG 変換は、奥村先生のTeX Wikiの1ページ(http://oku.edu.mie-u.ac.jp/~okumura/texwiki/?Ghostscript#g1adcf94)より

$ gs -q -dSAFER -dNOPAUSE -dBATCH -sDEVICE=pngalpha -dEPSCrop -r300 \
-dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sOutputFile=tmp.png input.eps

とすればできます。


EPSCrop オプションはEPSファイルのヘッダ中にある bounding box の指定を読み取り、その範囲のみを出力させるためのオプションです。これが無いと、用紙の左下隅に図が置かれたような出力になってしまいます。ここで注意すべきは、bounding box指定の読み取りは「gsがそのファイルがEPSであると認識した場合に限られる」ということです。今回の経験から、gsはファイル先頭のコメント行を頼りに判定を行っているらしいことが分かりました。
もし、ファイルの先頭行が

%!PS-Adobe-3.0

であれば、例え拡張子が.epsであってもbounding boxの処理は行われません。

%!PS-Adobe-3.0 EPSF-3.0

であれば、EPSと判定されるようです。


PNG -> EPS変換については以下を参考にしました。EPS -> PNGについても書かれています。
EPS figures and PDF conversion
http://electron.mit.edu/~gsteele/pdf/
ImageMagickのconvertコマンドを用いて

$ convert tmp.png eps3:output.eps

で完成です。


さて、最後に用いたconvertコマンドは多種多様な形式の画像ファイルを相互変換可能な、非常に高機能なプログラムです。もしかして、convertに掛かればEPS -> EPSのラスタライズなんて一発で出来るのでは?
やってみましょう。

% convert -verbose -density 300x300 input.eps eps3:output.eps
"gs" -q -dQUIET -dSAFER -dBATCH -dNOPAUSE -dNOPROMPT -dMaxBitmap=500000000 -dAlignToPixels=0 -dGridFitTT=2 "-sDEVICE=pngalpha" -dTextAlphaBits=4 -dGraphicsAlphaBits=4 "-r300x300" -g1200x1200  "-sOutputFile=/tmp/magick-XXYKHpB5" "-f/tmp/magick-XXFyuy9L" "-f/tmp/magick-XXXCYLHs"
/tmp/magick-XXYKHpB5 PNG 1200x1200 1200x1200+0+0 8-bit DirectClass 736KBB 0.050u 0:00.050
input.eps PS 1200x1200 1200x1200+0+0 16-bit DirectClass 736KBB 0.000u 0:00.009
input.eps=>output.eps PS 1200x1200 1200x1200+0+0 16-bit DirectClass 5.443MBB 0.540u 0:00.429

ご覧の通り、convertは内部でgsコマンドを呼び出し、我々が上でやったこととほぼ同じことをやってくれるようです。EPSCropあたりの動作が異なるようですが、まあ、上手くやってくれてるようです。


という訳で、convertコマンドは出来る子なので、困ったら彼に相談してみましょう。