#!/usr/local/bin/perl -w #### # # Image thumbnailer with similar image suggestion # # Copyright 2006, Simon Wistow # Released under the same terms as Perl itself # #### use strict; use Cwd; use Template; use File::Basename; use File::Type; use Image::Seek qw(loaddb add_image query_id savedb); use Image::Imlib2; use Digest::MD5 qw(md5_hex); use DBM::Deep; my $force_thumbs = 0; my $clean = 0; my $no_suggest = 0; while ($ARGV[0] =~ s!^-+!!) { my $arg = shift @ARGV; if ($arg eq 'force_thumbs') { $force_thumbs = 1; next; } if ($arg eq 'nuke') { $force_thumbs = 1; $clean = 1; next; } if ($arg eq 'clean') { $clean = 1; next; } if ($arg eq 'no_suggest') { $no_suggest = 1; next; } } my $db = "pics.db"; my $ids = "ids.db"; if ($clean) { unlink($db); unlink($ids); } loaddb($db); $ids = DBM::Deep->new( file => $ids, autoflush => 1 ); use vars qw(@pics); # work out our directory name my ($dir) = (getcwd =~ m!/([^/]+)$!); # create a directory for thumnails unless it already exists my $thumbdir = '.thumbs'; unless (-e $thumbdir && -d $thumbdir) { mkdir $thumbdir || die "Couldn't create a $thumbdir directory : $!\n"; } # construct a new File::Magic object for checking of files my $ft = File::Type->new; my $count = 0; my %files; # loop through each file passed foreach my $file (sort { $a cmp $b } @ARGV) { # don't need our selves or dot files next if $file eq $0; next if $file =~ /^\./; # get the type my $type = $ft->mime_type($file); # next if failure (which probably means it's a directory) next unless defined $type; # or if it's not an imgae next unless $type =~ /^image/; # split it up # my ($name, $path, $suffix) = fileparse($file, '\..+$'); # next unless $suffix; # # don't need to thumbnail thumbnails # next if $file =~ /_sm\./; # make the new name my $new = "$thumbdir/$file"; my $img = eval { Image::Imlib2->load($file) }; # skip if it's not valid unless ($img) { print STDERR "$file - couldn't open\n"; next; } my $w = $img->get_width(); my $h = $img->get_height(); # work out the scaling factor my $s = 240/$w; # don't scale up if we're smaller than the default $s = 1 if $s > 1; my $sw = $w * $s; my $sh = $h * $s; my $id = $ids->{files}->{$file}; if (!defined $id) { $ids->lock(); $id = ++$ids->{counter}; $ids->{files}->{$file} = $id; $ids->unlock(); } my $index = $clean; my $pic = { file => $file, thumb => $new, sw => $sw, sh => $sh, id => $id, }; $files{$id} = $file; # don't thumbnail if we've already one it goto PUSH if (-f $new && !$force_thumbs); $index = 1; # thumbnail the pic my $thumb = $img->create_scaled_image ($sw, $sh); my $res = eval { $thumb->save($new) }; unless (!$@) { print STDERR "$file - couldn't save\n"; next; } PUSH: # Add to the DB add_image($img, $pic->{id}) if $index && !$no_suggest; # do the pushing print STDERR "$file -> $new (id=".$pic->{id}.")\n"; push @pics, $pic; } use Data::Dumper; unless ($no_suggest) { foreach my $pic (@pics) { my @results = grep { $_->[0] != $pic->{id} } query_id($pic->{id}, 6); $pic->{like} = \@results; } } savedb($db); # print out the page my $template = join "", ; my $tt = Template->new || die "Couldn't load TT\n"; my $vars = { dir => ucfirst $dir, pics => \@pics, files => \%files, }; $tt->process(\$template, $vars) || die $tt->error(), "\n"; __DATA__ [% dir %]
[% USE Dumper %] [% FOREACH pic = pics %]


[% IF pic.like.size %] See also: [% FOREACH like = pic.like %] [% SET id = like.0 %] [% files.$id %]  [% END %] [% END %]

[% END %]

made with ..