135 lines
3.6 KiB
Perl
Executable File
135 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:
|