ImageMagickは、コマンドラインで画像ファイルを変換するのに最適なようです。ただし、ピクセル単位のサイズとピクセルあたりのインチ単位の解像度の変更のみがサポートされており、印刷サイズはサポートされていません(コマンドで表示identify -verbose
)。そうしたいです:
- 画像の印刷サイズをmm単位ですばやく取得
- 画像の印刷サイズを変更します(高さまたは幅、あるいはその両方をmm単位の新しい値に設定します)
これは簡単なシェルスクリプトでできるはずですよね?
ImageMagickは、コマンドラインで画像ファイルを変換するのに最適なようです。ただし、ピクセル単位のサイズとピクセルあたりのインチ単位の解像度の変更のみがサポートされており、印刷サイズはサポートされていません(コマンドで表示identify -verbose
)。そうしたいです:
これは簡単なシェルスクリプトでできるはずですよね?
画像の唯一の絶対寸法はピクセルです。
解像度、mm、または密度または解像度は、特定の表面 (画面表示、紙の印刷) で画像をレンダリングする場合にのみ機能します。
これらには、ハードウェアに依存する独自の組み込みの解像度があります。それがわかっている場合は、「自然なサイズ」でレンダリングする場合、画像の寸法のmm値を計算できます。
非常に多くの場合、「自然なサイズ」は必要ありません。場合によっては、「レターサイズの用紙に画像を入れる」(サイズに合わせて拡大縮小する) ことが必要な場合もあります。その場合、同じ画像を拡大または縮小する必要がありますが、画面またはプリンターの解像度は変更されません。補間アルゴリズムがピクセルを追加してギャップを埋める (拡大する) か、ピクセルを削除してピクセルを削除するだけです。画像を小さく表示します (縮小)。
そのため、誰かが「mm 単位の画像サイズ」(画像の自然なサイズ) を計算する方法についてアルゴリズムを提供する前に、ターゲット デバイス (画面またはプリンター) の解像度を知る必要があります。
編集:
特定の画像 (ピクセル単位のサイズ) を PDF (ソース ドキュメントがたとえば LaTeX から取得されたもの) に埋め込む場合、指定する必要があります...
イメージを再サンプリングしないと、これらの両方のパラメーターを同時に決定することはできません。1 つを選択すると、もう 1 つはその選択によって暗黙的に決定されます。
例を挙げると。
元の画像が 2160x1440 ピクセルであるとします。
LaTeX -> PDF 変換は Ghostscript によって行われます。Ghostscript は、すべてのラスター オブジェクトに対して 720 dpi のデフォルト解像度を内部的に使用します。そのため、PDF 変換で「解像度」を明示的に別の値に設定しない限り、PDF または印刷ページの画像は 3x2 インチ (76.2 x 50.8 mm) のサイズになります。
解像度を 90 dpi に設定すると、画像はページ上で 24x16 インチ (609.6 x 406.4 mm) のサイズになります。
解像度を 270 dpi (一般的に使用される 300 dpi に近い) に設定すると、画像サイズは 8x5.333 インチ (203.2 x 135.5 mm) に変換されます。
したがって、シェルスクリプトの式は次のとおりです。
# 25.4 mm == 1 inch
image_width_px=W # in pixels (integer)
image_height_px=H # in pixels (integer)
resolution=R # in pixels/inch
image_width_in_inch=$((W / R)) # Shell arithmetics: does only handle
image_height_in_inch=$((H / R)) #+ and return integers!
image_width_in_mm=$(( $((W / R)) * 254/10 ))
image_height_in_mm=$(( $((H / R)) * 254/10 ))
# use 'bc' to achieve higher precision arithmetics:
precise_image_width_in_mm=$( echo \
"$image_width_px / $resolution * 25.4" \
| bc -l )
precise_image_height_in_mm=$( echo \
"$image_height_px / $resolution * 25.4" \
| bc -l )
Perl で独自のスクリプトを使用して解決しようとしました。Kurt Pfeilfe の回答で説明されているように、ピクセル単位のサイズと要求された印刷サイズに基づいて、1 インチあたりのドット数を計算する必要があります。
sub getsize {
my $file = shift;
my $info = do { # avoid the shell, no escaping needed
my @args = ('-format','%G %x%y','-units','PixelsPerInch',$file);
open my $fh, "-|", "identify", @args or die "$!\n";
<$fh>;
};
if ($info =~ /^(\d+)x(\d+) (\d+) PixelsPerInch(\d+) PixelsPerInch/) {
my ($px,$py,$dx,$dy) = ($1,$2,$3,$4);
my ($sx,$sy) = map { $_ * 25.4 } ($px/$dx, $py/$dy);
return ($px,$py,$dx,$dy,$sx,$sy);
} else {
die $info;
}
}
foreach my $file (@ARGV) {
if ($file =~ /^(\d*)(x(\d+))?mm$/) {
($mx,$my) = ($1,$3);
} elsif( -e $file ) {
my ($w,$h);
if ($mx || $my) {
my ($px,$py,$dx,$dy,$sx,$sy) = getsize($file);
my $rx = 25.4 * ( $mx ? ($px/$mx) : ($py/$my) );
my $ry = 25.4 * ( $my ? ($py/$my) : ($px/$mx) );
system qw(convert -units PixelsPerInch -density),
sprintf("%.0fx%.0f",$rx,$ry), $file, $file;
}
printf "$file: %dx%d at %dx%ddpi = %dx%dmm", getsize($file);
} else {
die "file not found: $file\n";
}
}
スクリプトはミリ単位の分数をサポートしていません。ソースを自由に変更してください。