2

我正在尝试使用 ImageMagick 和 perlmagick (Image::Magick) 对图像进行一些批量调整大小操作。我作为源的所有图像都是大图像,我想将它们调整为不同的间隔或高度或宽度。我想始终保持纵横比。

给定一个尺寸为 3840 像素 × 2160 像素 (3840x2160) 的示例图像,我想创建以下调整大小的图像:

    ?x1000
    ?x500
    ?x100
    1600x?
    1200x?
    800x?
    400x?

我可以通过以下命令(按顺序)使用convert命令行实用程序非常简单地做到这一点:

    convert input_filename.jpg -resize x1000 output_wx1000.jpg
    convert input_filename.jpg -resize x500  output_wx500.jpg
    convert input_filename.jpg -resize x100  output_wx100.jpg
    convert input_filename.jpg -resize 1600  output_1600xh.jpg
    convert input_filename.jpg -resize 1200  output_1200xh.jpg
    convert input_filename.jpg -resize 800   output_800xh.jpg
    convert input_filename.jpg -resize 400   output_400xh.jpg

由于我试图与其他操作一起批量执行这些操作,因此我试图在 perl 中使用Image::Magick执行这些相同的操作。我尝试了几种不同的方法,结果如下:

#METHOD 1
    my $image = Image::Magick->new();
    $image->Read($input_filename);
    $image->Resize(
        ($width  ? ('width'  => $width)  : ()),
        ($height ? ('height' => $height) : ()),
    );
    $image->Write(filename => $output_filename);

这会导致图像不保持纵横比。例如,如果提供 100 的高度,则输出图像将是原始宽度乘以 100 (3840x100)。提供宽度时会产生类似的效果——保持高度,但不保持纵横比。

#METHOD 2
    my $image = Image::Magick->new();
    $image->Read($input_filename);
    die "Only one dimension can be supplied" if $width && $height;
    $image->Resize(geometry => $width) if $width;
    $image->Resize(geometry => "x$height") if $height;
    $image->Write(filename => $output_filename);

这导致图像保持纵横比,如果几何操作基于高度,则输出正是预期的。但是,如果提供了宽度,则输出非常模糊。

#METHOD 3
    `convert "$input_filename" -resize $width   "$output_filename"` if $width;
    `convert "$input_filename" -resize x$height "$output_filename"` if $height;

这导致图像都是正确的,但在 perl 进程之外分叉会导致效率问题。

perl 中是否有更好的方法来使此调整大小操作产生与命令行转换实用程序相同的结果?

我的命令行实用程序报告版本 6.7.9-10,Image::Magick 报告版本 6.79。

4

2 回答 2

2

您的方法#2 是在正确的轨道上。要保持纵横比,请通过geometry关键字提供宽度和高度。通过在一次调用而不是两次调用中执行调整大小,可以使您的过程更通用:

$image->Resize(geometry => "${width}x${height}");

这确保了 Resize 只会被调用一次,即使你同时提供了 $width 和 $height。只需确保如果未提供任一值,则将其设置为空字符串。如果您在方法 #2 中为您的过程提供了宽度和高度,那可能是您看到的模糊的原因。

另一个可能的模糊来源是调整大小运算符使用的过滤器。用于给定操作的最佳过滤器取决于图像的颜色特征以及原始尺寸和目标尺寸之间的关系。我建议阅读http://www.imagemagick.org/script/command-line-options.php#filter以了解相关信息。在 PerlMagick 中,您可以通过filter关键字指定要使用的 Resize 过滤器。

也就是说,我没有发现我尝试过的图像模糊的特别问题,所以如果问题仍然存在,测试图像将是最有帮助的。

于 2014-03-11T17:32:26.760 回答
0

我参加这个聚会可能有点晚了,但因为我有一个非常相似的目标——调整图像大小并在图像质量和它占用的磁盘空间量之间保持平衡——我想出了以下代码。我从 OPs 代码开始,并关注了这篇非常有趣的文章:https ://www.smashingmagazine.com/2015/06/efficient-image-resizing-with-imagemagick/

这是结果:

sub optimize_image_size
{
my $imagePath = shift();
my $height = shift(); #720
my $width = shift(); #1080

 my $image = Image::Magick->new();
    $image->Read($imagePath);
    die "Only one dimension can be supplied" if $width && $height;
    $image->Thumbnail(geometry => "$width",filter=>'Triangle') if $width;
    $image->Thumbnail(geometry => "x$height",filter=>'Triangle') if $height;
    $image->Colorspace(colorspace=>'sRGB');
    $image->Posterize(levels=>136, dither=>'false');
    $image->UnsharpMask(radius=>0.25, sigma=>0.25, threshold=>0.065, gain=>8);
    $image->Write(filename => $imagePath
            , quality=>'82'
            , interlace=>'None'
    );

}

至少对我来说,它产生了非常令人满意的尺寸缩小(我的 6MB 样本图像减少到大约 90Kb),同时保持类似于 Photoshop 的“网页版”设置的质量,当然无论您提供宽度还是高度都保持纵横比。

对于 OP 来说为时已晚,但也许它可以帮助其他人。

于 2021-04-05T15:10:39.623 回答