首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >图像:Magick (perlmagick)调整高宽比和质量问题(与转换命令行实用程序不同)

图像:Magick (perlmagick)调整高宽比和质量问题(与转换命令行实用程序不同)
EN

Stack Overflow用户
提问于 2014-03-08 16:54:18
回答 2查看 4.8K关注 0票数 2

我试图使用ImageMagick和perlmagick (Image::Magick)对图像进行批量调整操作。所有作为源的图像都是大型图像,我希望将它们调整到不同的间隔或高度或宽度。我想永远保持高宽比。

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

代码语言:javascript
复制
    ?x1000
    ?x500
    ?x100
    1600x?
    1200x?
    800x?
    400x?

我可以非常简单地使用下面的命令(按顺序)使用转换命令行实用程序来完成这个任务:

代码语言:javascript
复制
    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

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

代码语言:javascript
复制
#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)。当提供一个宽度时,会产生类似的效果--高度保持不变,但高宽比不是。

代码语言:javascript
复制
#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);

这将导致图像保持高宽比,如果几何操作是基于高度的,则输出正是所期望的。但是,如果提供了一个宽度,输出就会非常模糊。

代码语言:javascript
复制
#METHOD 3
    `convert "$input_filename" -resize $width   "$output_filename"` if $width;
    `convert "$input_filename" -resize x$height "$output_filename"` if $height;

这导致了所有的图像都是正确的,但是在perl进程之外出现了分叉,从而导致了效率问题。

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

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

EN

回答 2

Stack Overflow用户

发布于 2014-03-11 17:32:26

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

代码语言:javascript
复制
$image->Resize(geometry => "${width}x${height}");

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

另一个可能的模糊源是调整大小操作符使用的过滤器。用于给定操作的最佳滤波器取决于图像的颜色特性和原始维度与目标维度之间的关系。我建议通过http://www.imagemagick.org/script/command-line-options.php#filter阅读有关这方面的信息。在PerlMagick中,可以通过filter关键字指定用于调整大小的筛选器。

尽管如此,我并没有发现我尝试过的图像模糊的特殊问题,所以如果问题持续存在,测试图像将是最有帮助的。

票数 2
EN

Stack Overflow用户

发布于 2021-04-05 15:10:39

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

其结果是:

代码语言:javascript
复制
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的样本图像被减少到大约90 if ),同时保持一个类似Photoshop的质量“为网络”设置,当然保持纵横比,无论你提供的宽度或高度。

做手术太晚了,但可能对其他人有帮助。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/22272229

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档