在Perl中查找具有最小宽度和高度的jpg

时间:2014-10-31 20:37:45

标签: linux windows perl

我正在寻找一种方法来找到(1)具有最小宽度和(2)最小高度的文件并显示这些数字(最好是命令行,Linux或Windows)。我不知道使用什么工具,但我认为Perl与其中一个软件包可能具有这种功能。

3 个答案:

答案 0 :(得分:1)

在Linux上,我只是从命令行使用ImageMagick。您可能需要先安装它(例如在Ubuntu上使用sudo apt-get install imagemagick):

narrowest=$(identify *jpg | sort -nr -k3 | tail -n 1 | cut -d\[ -f1)
shortest=$(identify *jpg | sort -tx -nr -k2 | tail -n 1 | cut -d\[ -f1)

在Windows上,除非您安装Cygwin或其他东西,否则这不是一个选项。

在Linux和Windows上,您可以使用Image::Magick模块从Perl访问该功能,但您必须自己安装该模块。请参阅Borodin对代码的回答。

答案 1 :(得分:1)

我会为该任务推荐模块Image::Size。与像Image::Magick这样的完整图像处理库相比,它不会将整个图像解压缩并读取到内存中以获得其大小。所以它应该更快,更少内存,特别是对于大型图像。

以下几行应该有效:

use strict;
use warnings;

use Image::Size;

my ($min_width, $min_height);

for my $filename (glob '*.jpg') {
    my ($width, $height) = imgsize($filename);
    $min_width  = $width  if !defined($min_width)  || $width < $min_width;
    $min_height = $height if !defined($min_height) || $height < $min_height;
}

if (defined($min_width) && defined($min_height)) {
    print "Minimum width: $min_width\n";
    print "Minimum height: $min_height\n";
}
else {
    print "No images found\n";
}

答案 2 :(得分:0)

这是一个完整的Perl程序,可以按照您的要求执行。您可能必须安装Image::Magick,因为它不是核心模块。按照目前的情况,程序会检查当前工作目录中以.jpg结尾的所有文件。您可能希望将呼叫更改为glob以检查其他目录中的文件或使用不同的文件类型。

use strict;
use warnings;

use Image::Magick;

my %data;
for my $jpg (glob '*.jpg') {
    my $magick = Image::Magick->new;
    $magick->Read($jpg);
    $data{$jpg} = { map { $_ => $magick->Get($_) } qw/ width height / };
} 

my ($least_width,  $least_width_file);
my ($least_height, $least_height_file);

while (my ($jpg, $info) = each %data) {

    unless ($least_width and $least_width <= $info->{width}) {
      ($least_width_file, $least_width) = ($jpg, $info->{width});
    }

    unless ($least_height and $least_height <= $info->{height}) {
      ($least_height_file, $least_height) = ($jpg, $info->{height});
    }
}

print "\n";
printf "File with least width (%d) is %s\n", $least_width, $least_width_file; 
printf "File with least height (%d) is %s\n", $least_height, $least_height_file; 

<强>更新

要关注@ nwellnhof的建议并使用Image::Size代替Image::Magick,您应该使用以下代码替换use语句和for循环。

use Image::Size qw/ imgsize /;

my %data;
for my $jpg (glob '*.jpg') {
    @{ $data{$jpg} }{qw/ width height /} = imgsize($jpg);
} 

<强>更新

此版本会根据请求向输出添加一些统计信息。它使用List::UtilsBy模块更简洁地查找最小的文件。这不是一个核心模块,很可能需要安装。

use strict;
use warnings;

use Image::Size qw/ imgsize /;
use List::UtilsBy qw/ min_by /;

my %data;
for my $jpg (glob '*.jpg') {
    @{ $data{$jpg} }{qw/ width height /} = imgsize($jpg);
} 

my @least_width_files  = min_by { $data{$_}{width} }  keys %data;
my $least_width = $data{$least_width_files[0]}{width};

my @least_height_files = min_by { $data{$_}{height} } keys %data;
my $least_height = $data{$least_height_files[0]}{height};

print "\n";
if (@least_width_files == keys %data) {
    printf "All files have a width of %d\n", $least_width;
}
else {
    my $n = @least_width_files;
    printf "%d file%s %s the least width of %d:\n", $n, $n == 1 ? ('', 'has') : ('s', 'have'), $least_width;
    print "    $_\n" for @least_width_files;
}

print "\n";
if (@least_height_files == keys %data) {
    printf "All files have a height of %d\n", $least_height;
}
else {
    my $n = @least_height_files;
    printf "%d file%s %s the least height of %d:\n", $n, $n == 1 ? ('', 'has') : ('s', 'have'), $least_height;
    print "    $_\n" for @least_height_files;
}