happens (sometimes) when the image was edited somehow in an editing program, and the program forgot to append the original EXIF data to the exported image. This is why I've changed the way the size (x, y) of an image is acquired. Instead of looking at the EXIF data, I'm using a module that actually READS the size from the image. Kudos to the author.
134 lines
3.6 KiB
Perl
Executable File
134 lines
3.6 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use warnings;
|
|
use strict;
|
|
|
|
use File::Find::Wanted;
|
|
use File::Basename;
|
|
use File::Spec;
|
|
use File::Spec::Functions;
|
|
use Image::Size;
|
|
use Data::Dumper::Simple;
|
|
use Math::Round;
|
|
|
|
my $conf = {
|
|
src_dir => "./slike",
|
|
dst_dir => "./linki",
|
|
debug => 0,
|
|
};
|
|
|
|
sub msg {
|
|
my $text = shift;
|
|
print $text;
|
|
}
|
|
|
|
sub msg_error {
|
|
my $text = shift;
|
|
print STDERR "ERROR: $text";
|
|
}
|
|
|
|
sub msg_warn {
|
|
my $text = shift;
|
|
print STDERR "warning: $text";
|
|
}
|
|
|
|
sub msg_debug {
|
|
my $text = shift;
|
|
print "$text" if $conf->{debug};
|
|
}
|
|
|
|
# verify the source dir
|
|
if (! -d $conf->{src_dir}) {
|
|
msg_error "Source directory '$conf->{src_dir}' does not exist. Aborting.\n" ;
|
|
exit 1;
|
|
}
|
|
|
|
# verify the destination dir
|
|
if (! -d $conf->{dst_dir}) {
|
|
msg_error "Destination directory '$conf->{dst_dir}' does not exist. Aborting.\n";
|
|
exit 1;
|
|
}
|
|
|
|
# gather the list of files
|
|
my @list = find_wanted(
|
|
sub { -f && ( /\.jpg$/i || /\.jpeg$/i ) },
|
|
$conf->{src_dir}
|
|
);
|
|
if (! @list) {
|
|
msg "No files found.\n";
|
|
exit 0
|
|
}
|
|
|
|
# Go through all the image files and build the hash that holds all the
|
|
# information about them.
|
|
my $count = 0; # how many files?
|
|
my $errors = 0; # how many errors?
|
|
my $ars = {}; # a hashref that holds all the encountered aspect rations and their number of occurence
|
|
my $files = {}; # a hashref that holds all the files, their exif data, and their calculcated aspect ratio
|
|
foreach my $f (@list) {
|
|
$count++;
|
|
msg "Gathering sizes for image in file: '$f'\n";
|
|
(my $x, my $y) = imgsize($f);
|
|
|
|
# calculate aspect ratio
|
|
my $ar;
|
|
if ($x and $y) {
|
|
$ar = nearest(0.1, ($x > $y) ? $x / $y : $y / $x);
|
|
$ars->{$ar}++;
|
|
}
|
|
else {
|
|
$errors++;
|
|
}
|
|
|
|
# append the stuff to hash
|
|
$files->{$f}->{x} = $x;
|
|
$files->{$f}->{y} = $y;
|
|
$files->{$f}->{ar} = $ar;
|
|
}
|
|
|
|
# Dump the hash data if we are in debug mode.
|
|
if ($conf->{debug}) {
|
|
msg_debug "All images and their data:\n";
|
|
print Dumper $files;
|
|
msg_debug "\n";
|
|
}
|
|
|
|
# Dump some statistics.
|
|
msg "Number of images found: $count. Number of images with errors: $errors.\n";
|
|
msg "Aspect ratio information for all images (aspect ratio => number of occurences):\n";
|
|
print Dumper $ars;
|
|
|
|
# Create destination directories. TODO: use something smarter than just string
|
|
# concatenation.
|
|
msg_debug "Creating destination directories: ";
|
|
foreach my $d (keys %$ars) {
|
|
my $dirname = $conf->{dst_dir} . "/" . $d;
|
|
msg_debug "'$dirname' ";
|
|
mkdir $dirname;
|
|
}
|
|
msg_debug "\n";
|
|
|
|
# Symlink
|
|
msg "Symlinking source files into destination directories.\n";
|
|
foreach my $f (keys %$files) {
|
|
next unless exists $files->{$f}->{ar};
|
|
|
|
# Construct the path of the symlink. This is quite tricky to get right.
|
|
# TODO: use something smarter than just string concatenation.
|
|
msg_debug "\$f='$f' ";
|
|
my $ar = $files->{$f}->{ar}; msg_debug "\$ar='$ar' ";
|
|
my $symlink_dir = $conf->{dst_dir} . "/" . $ar; msg_debug "\$symlink_dir='$symlink_dir' ";
|
|
my $symlink = $symlink_dir . "/" . basename($f); msg_debug "\$symlink='$symlink' ";
|
|
my $symlink_dst = File::Spec->abs2rel(
|
|
File::Spec->rel2abs($f),
|
|
File::Spec->rel2abs($symlink_dir)
|
|
); msg_debug "\$symlink_dst='$symlink_dst' ";
|
|
msg_debug "\n";
|
|
|
|
# Create the symlink.
|
|
msg_debug "symlink($symlink_dst, $symlink);\n";
|
|
symlink($symlink_dst, $symlink);
|
|
}
|
|
|
|
# vim: set ts=4 sw=4 et cc=80:
|