ImageMagick 似乎最好在命令行上转换图像文件。但是,它只支持更改像素大小和每像素英寸分辨率,但不支持更改打印大小(如命令所示identify -verbose
)。我想:
- 快速获取以mm为单位的图像打印尺寸
- 更改图像打印尺寸(通过将高度或宽度或两者都设置为以毫米为单位的新值)
这应该可以通过简单的 shell 脚本来实现,不是吗?
ImageMagick 似乎最好在命令行上转换图像文件。但是,它只支持更改像素大小和每像素英寸分辨率,但不支持更改打印大小(如命令所示identify -verbose
)。我想:
这应该可以通过简单的 shell 脚本来实现,不是吗?
图像的唯一绝对维度是像素。
分辨率、毫米或密度或分辨率只有在您在特定表面(屏幕显示、纸张打印输出)上渲染图像时才会发挥作用。
它们有自己的内置的、硬件相关的分辨率。如果您知道,您可以计算图像尺寸的mm值,前提是您希望以“自然尺寸”呈现它。
很多时候你不想要“自然尺寸”——有时你可能想要:“用图像填充 Letter 大小的纸”(缩放到适合)。如果发生这种情况,则必须放大或缩小相同的图像 - 但屏幕或打印机分辨率不会改变,只是插值算法将开始添加像素以填充间隙(放大)或删除像素以使图片看起来更小(按比例缩小)。
因此,在有人给出关于如何计算“以 mm 为单位的图像大小”(以图像的自然大小)的算法之前,您需要知道目标设备(屏幕或打印机)的分辨率。
编辑:
如果您将给定的图像(其大小以像素为单位)嵌入 PDF(源文档来自 LaTeX),您仍然必须指定...
如果不对图像进行重新采样,您无法同时确定这两个参数。选择一个,另一个由您的选择隐含地确定。
举个例子。
假设您的原始图像是 2160x1440 像素。
您的 LaTeX -> PDF 转换由 Ghostscript 完成。Ghostscript 在内部对所有光栅对象使用 720 dpi 的默认分辨率。因此,除非您为 PDF 转换明确设置“分辨率”为不同的值,否则 PDF 或打印页面上的图像尺寸将为 3x2 英寸(76.2 x 50.8 毫米)。
如果将分辨率设置为 90 dpi,则页面上的图像尺寸为 24x16 英寸(609.6 x 406.4 毫米)。
如果将分辨率设置为 270 dpi(接近常用的 300 dpi),图像尺寸将转换为 8x5.333 英寸(203.2 x 135.5 毫米)。
所以shell脚本的公式是:
# 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 在他的回答中所解释的那样,必须根据像素大小和请求的打印大小来计算每英寸的点数。
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";
}
}
该脚本不支持毫米的分数,请随意修改源代码。