2014-10-31 49 views
0

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

回答

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; 
} 
+0

感谢!我将在明天在Windows和Linux上检查并告诉结果。 – menteith 2014-11-01 20:07:34

+1

如果你只关心图像大小,我发现['Image :: Size'](https://metacpan.org/pod/Image::Size)是一个优秀的,更轻量级的模块。 – nwellnhof 2014-11-02 12:48:11

+0

@nwellnhof:我认为你应该把它写成解决方案 – Borodin 2014-11-02 13:42:55

1

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

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

在Perl中,你可以使用[图像:: Magick(http://p3rl.org/Image::Magick)。 – choroba 2014-10-31 20:46:50

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"; 
} 
+0

很棒!我在Windows上安装Image :: Magick时遇到了问题。你的解决方案非常快,并且完成这项工作。非常感激! – menteith 2014-11-02 17:56:39

+0

我也很感激,如果你可以添加两个twings。首先,脚本可以显示文件的名称(最小宽度和最高)。其次,所有文件具有相同宽度和高度(如果是这种情况)的信息也会非常好。 – menteith 2014-11-02 18:03:31

+0

@menteith StackOverflow不是其他人可以免费解决所有问题的网站。你的问题的答案应该为你提供足够的细节来完成工作。 – nwellnhof 2014-11-02 21:04:41

相关问题