現在の顧客はカタログで販売していた商品/サービスを Web システムに展開した経緯があり、「印刷会社から DTP データを受け取って Web サイトに載せる」という作業が多いのですが。
今日も受け取った画像ファイルが .eps ファイルだったので、Web サイトに載せるべく .jpg 等に変換する方法を調べてみると、
というページがヒットしまして。
ページ先頭にあるように ImageMagick を使えば早いんですが、気づかずに eps2jpg(eps2png)でがんばってしまったので、とりあえずハマった点のメモです。ImageMagick は CMYK データ(?)で色がおかしくなってしまうことがあるようですし、何か役にたつかもしれません。
前提
- ActivePerl と Ghostscript は元々入ってたのでその手順は書きません
- Windows XP、ActivePerl 5.8.9.825、Ghostscript 9.00 の環境で試しました
eps2jpg のインストール
(2011-01-15 追記)私が編集したバージョンへのリンクが最後のほうにありますので、よろしければそちらをお使いください。
CPAN モジュールなら cpan コマンドでインストールできると思ったんですが、なぜかうまくいきませんでした。このページに解説があるとおり、CPAN 内のページ から「Download」をクリックして .tar.gz を落とすのがいいみたいです。
展開して src/eps2png.pl をパスが通ってる場所にコピーします。私は Ghostscript のパス(C:\gs\gs9.00-\bin)に入れておきました。
このとき eps2jpg 等の別名でコピーしておき、perl eps2jpg のように実行すると、-jpg 等のオプションを省略できるので楽なんですが、スクリプトのフルパスを指定するのは面倒ですし、後述するようにスクリプトに変更が必要だったりもするので私はコピーしていません。
eps2png.pl のエラー回避1
(2011-01-15 追記)こちらも末尾のバージョンを使えば不要です。
ではさっそく
eps2png.pl -resolution 300 -verbose -trace C:\001_1.eps
のようにして実行してみると・・・(元サイトを真似て -resolution を指定していますが、あまり意味はありません。また、ここではあまり関係ありませんが、エラーを追いやすいように -trace オプションをつけています。)
Producing png (png16m) image. No bounding box in C:\001_1.eps
のようなエラーになってしまいます。
原因は .eps ファイルが改行コード CR で生成されていたことで、XMP を見ると xmp:CreatorTool が「Adobe Photoshop CS4 Macintosh」になっていたので、よくわかりませんが Macintosh で生成されるとこうなるみたいです。
対策は、ファイル読み込み処理の前(適当でいいです。16 行目あたり?)に
$/ = "\r";
を入れること。これだと改行コード CR で決め打ちになってしまうのであまり汎用性はないのですが、とりあえず回避策ということで。
eps2png.pl のエラー回避2
スクリプトを変更して再度実行すると、
Producing png (png16m) image. C:\001_1.eps: x0=0, y0=0, w=175, h=126, width=730, height=526 Creating C:\001_1.png + gs -q -dNOPAUSE -r300 -g730x526 -dTextAlphaBits=4 -dGraphicsAlphaBits=4 -sDEVICE=png16m -sOutputFile=C:\001_1.png - >> (C:\001_1.eps) run >> showpage >> quit Error: /ioerror in --run-- Operand stack: (C:\001_1.eps) (r) Execution stack: %interp_exit .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- --nostringval-- --nostringval-- fa lse 1 %stopped_push 1942 1 3 %oparray_pop 1941 1 3 %oparray_pop 1925 1 3 %oparray_pop 1819 1 3 %oparray_pop --nostringval- - %errorexec_pop .runexec2 --nostringval-- --nostringval-- --nostringval-- 2 %stopped_push --nostringval-- 1942 1 3 %oparray_pop --nos tringval-- Dictionary stack: --dict:1166/1684(ro)(G)-- --dict:0/20(G)-- --dict:79/200(L)-- Current allocation mode is local Last OS error: Invalid argument GPL Ghostscript 9.00: Unrecoverable error, exit code 1 cmd close:
のようなエラーになってしまいます。
まあパスの扱いが怪しそうなので、
eps2png.pl -resolution 300 -verbose -trace C:/001_1.eps
のようにパスの区切りを「\」でなく「/」にするとうまく動作して、C:/001_1.png が生成されました。
.jpg を生成するには、
eps2png.pl -jpg -resolution 300 -verbose -trace C:/001_1.eps
のように -jpg オプションとかを付加すればよいです。
あとは -width 等を適切に設定すれば完了、と。縮小アルゴリズムは Nearest neighbor 法か何かで汚い感じなので、一度大きめの画像で出力して縮小したほうがよさそうです。
2011-01-15 追記
受領した .eps に改行コード CR のものと LF のものが混ざっていたようで、CR 固定ではうまく動作しませんでした。
どちらでも動作するように変更したバージョンを
に置いていますので、よろしければどうぞ。
diff はこんな感じです。(gist に変更前のバージョンあげておけば gist 側で diff 見れたんでしょうけど・・・取り急ぎ。)
--- eps2png.pl.org Wed May 20 22:55:23 2009 +++ eps2png.pl Fri Jan 14 12:11:02 2011 @@ -69,9 +69,21 @@ next; } - my $line = <EPS>; - unless ( $line =~ /^%!PS-Adobe.*EPSF-/ ) { - print STDERR ("Not EPS file: $eps_file, skipped\n"); + my $eol; + do { + local $/; + my $buffer = <EPS>; + unless ( $buffer =~ /%!PS-Adobe[-\d.]* EPSF-[\d.]*([\r\n])/ ) { + print STDERR ("Not EPS file: $eps_file, skipped\n"); + $err++; + next; + } + $eol = $1; + }; + $/ = $eol; + + unless ( open (EPS, $eps_file) ) { + print STDERR ("Cannot open $eps_file [$!], skipped\n"); $err++; next; } @@ -85,7 +97,7 @@ my $width = $width; my $height = $height; - while ( $line = <EPS> ) { + while ( my $line = <EPS> ) { # Search for BoundingBox. if ( $line =~ /^%%BoundingBox:\s*(\S+)\s+(\S+)\s+(\S+)\s+(\S+)/i ) {
- ファイルを一気に読み込んで EPS のヘッダを探す
- サムネイルつきのもの(?)は先頭にバイナリデータが大量に入っていて、「先頭の n バイトを読んでチェックする」みたいな手が使えなかったので
- EPS ヘッダ行末の改行コードを区切り文字としてファイルを読み込みなおす
というような処理になっています。
あと、Windows 環境で実行すると、Shift_JIS の 2 byte 目が \x5c になっているファイルでエラーになってしまうようです。回避策はよくわからなかったので、一旦日本語を含まないファイルにコピーして変換をかけて回避しています。