1

ImageMagick 似乎最好在命令行上转换图像文件。但是,它只支持更改像素大小和每像素英寸分辨率,但不支持更改打印大小(如命令所示identify -verbose)。我想:

  • 快速获取以mm为单位的图像打印尺寸
  • 更改图像打印尺寸(通过将高度或宽度或两者都设置为以毫米为单位的新值)

这应该可以通过简单的 shell 脚本来实现,不是吗?

4

2 回答 2

3

图像的唯一绝对维度是像素

分辨率毫米密度分辨率只有在您在特定表面(屏幕显示、纸张打印输出)上渲染图像时才会发挥作用。

它们有自己的内置的、硬件相关的分辨率。如果您知道,您可以计算图像尺寸的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 )
于 2012-08-02T10:20:20.413 回答
2

我试图用我自己的 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";
  }
}

该脚本不支持毫米的分数,请随意修改源代码

于 2012-08-03T11:31:47.913 回答