From bfa0d113c413c2431f72405623d79cbc7b0b40f2 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 23 Dec 2012 22:50:57 +0100 Subject: [PATCH] Gallery2: Generator --- gal2/FORMAT | 25 +++++++++ gal2/UCW/Gallery.pm | 20 +++++++ gal2/gal-gen | 128 ++++++++++++++++++++++++++++++++++++++++++++ gal2/gal-scan | 2 +- 4 files changed, 174 insertions(+), 1 deletion(-) create mode 100644 gal2/FORMAT create mode 100755 gal2/gal-gen diff --git a/gal2/FORMAT b/gal2/FORMAT new file mode 100644 index 0000000..b7a67fd --- /dev/null +++ b/gal2/FORMAT @@ -0,0 +1,25 @@ +List of photos (gallery.list) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +One photo per line, tab-separated columns: + + File name (relative to OrigDir in config) + Identifier (16 hex digits) + Orientation: one of "l", "r", "d", "." + Transformation -- sequence of: + n normalize contrast + s sharpen + h equalize histogram + Title (UTF-8 string) + +Lines starting with "#" are ignored. + + +Photo meta-data (gallery.meta in PhotoDir) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +Perl Storable containing a single hash. + +$meta->{photo}->{$identifier} is a hash of: + o orientation + xf transformation applied + w width after scaling + h height after scaling diff --git a/gal2/UCW/Gallery.pm b/gal2/UCW/Gallery.pm index b2d41a6..f13889d 100644 --- a/gal2/UCW/Gallery.pm +++ b/gal2/UCW/Gallery.pm @@ -6,6 +6,8 @@ package UCW::Gallery; use strict; use warnings; +use Storable; + BEGIN { # Standard Perl module stuff use Exporter(); @@ -39,6 +41,8 @@ BEGIN { $CF{'OrigDir'} = '.'; $CF{'PhotoDir'} = 'photo'; $CF{'CacheDir'} = "cache", + $CF{'PhotoMaxWidth'} = 1024, + $CF{'PhotoMaxHeight'} = 1024, } sub LoadConfig() { @@ -99,4 +103,20 @@ sub ReadList($) { return \@images; } +sub WriteMeta($$) { + my ($file, $meta) = @_; + open META, '>', "$file.new" or die "Cannot create $file.new: $!\n"; + Storable::nstore_fd($meta, \*META); + close META; + rename "$file.new", $file or die "Cannot rename $file.new to $file: $!\n"; +} + +sub ReadMeta($) { + my ($file) = @_; + open META, '<', $file or die "Cannot read $file: $!\n"; + my $meta = Storable::fd_retrieve(\*META) or die "Cannot parse $file\n"; + close META; + return $meta; +} + 1; diff --git a/gal2/gal-gen b/gal2/gal-gen new file mode 100755 index 0000000..970e3d2 --- /dev/null +++ b/gal2/gal-gen @@ -0,0 +1,128 @@ +#!/usr/bin/perl +# UCW Gallery: Generate published photos +# (c) 2004--2012 Martin Mares + +use strict; +use warnings; + +use lib '/home/mj/web/gal2'; +use UCW::Gallery; + +use File::Spec; +use Image::Magick; +use IO::Handle; +use File::Spec; +use File::Path; + +STDOUT->autoflush(1); + +UCW::Gallery::LoadConfig; + +my $orig_dir = $UCW::Gallery::CF{'OrigDir'}; +my $orig_list = UCW::Gallery::ReadList('gallery.list') or die "Cannot read gallery.list: $!\n"; + +my $photo_dir = $UCW::Gallery::CF{'PhotoDir'}; +if (-d $photo_dir) { + print "Using existing output directory $photo_dir\n"; +} else { + print "Creating output directory $photo_dir\n"; + File::Path::mkpath($photo_dir) or die "Unable to create $photo_dir: $!\n"; +} + +my $photo_meta = $photo_dir . "/gallery.meta"; +my $old_meta = {}; +if (-f $photo_meta) { + print "Reading old meta-data\n"; + $old_meta = UCW::Gallery::ReadMeta($photo_meta); + # use Data::Dumper; print "Read old meta: ", Dumper($old_meta), "\n"; +} +my $meta = { 'photo' => {} }; + +for my $f (@$orig_list) { + my $id = $f->{id}; + my $rotate = $f->{orientation}; + my $xfrm = $f->{xfrm}; + print "$id: "; + + my $p = new Image::Magick; + my $orig = File::Spec->rel2abs($f->{file}, $UCW::Gallery::CF{'OrigDir'}); + my ($orig_w, $orig_h, $orig_size, $orig_format) = $p->PingImage($orig) or die "Error reading $orig\n"; + print "${orig_w}x${orig_h} "; + + my ($w0, $h0) = ($rotate eq "l" || $rotate eq "r") ? ($orig_h, $orig_w) : ($orig_w, $orig_h); + my ($w, $h) = ($w0, $h0); + if ($w > $UCW::Gallery::CF{'PhotoMaxWidth'}) { + my $s = $UCW::Gallery::CF{'PhotoMaxWidth'} / $w; + $w = $w * $s; + $h = $h * $s; + } + if ($h > $UCW::Gallery::CF{'PhotoMaxHeight'}) { + my $s = $UCW::Gallery::CF{'PhotoMaxHeight'} / $h; + $w = $w * $s; + $h = $h * $s; + } + $w = int($w); + $h = int($h); + + my $m = { + 'o' => $rotate, + 'xf' => $xfrm, + 'w' => $w, + 'h' => $h, + }; + + my $om = $old_meta->{photo}->{$id}; + if ($om && + $om->{o} eq $m->{o} && + $om->{xf} eq $m->{xf} && + $om->{w} eq $m->{w} && + $om->{h} eq $m->{h}) { + # FIXME: Remove old images? + print "... uptodate\n"; + $meta->{photo}->{$id} = $om; + next; + } + + my $e; + $e = $p->Read($orig) and die "Error reading $orig: $e"; + $p->Strip; + $p->SetAttribute(quality=>90); + + if ($xfrm =~ /s/) { + print "-> sharpen "; + $p->Sharpen(1); + } + if ($xfrm =~ /h/) { + print "-> equalize "; + $p->Equalize(); + } + if ($xfrm =~ /n/) { + print "-> normalize "; + $p->Normalize(); + } + + my $rot = 0; + if ($rotate eq "l") { $rot = 270; } + elsif ($rotate eq "r") { $rot = 90; } + elsif ($rotate eq "u") { $rot = 180; } + if ($rot) { + print "-> rotate $rot "; + $p->Rotate(degrees=>$rot); + } + + if ($w != $w0 || $h != $h0) { + print "-> ${w}x${h} "; + $p->Resize(width=>$w, height=>$h); + } + + my $photo = File::Spec->catfile($photo_dir, $id . ".jpg"); + my $tmp = "$photo.new"; + $e = $p->Write($tmp) and die "Unable to write $tmp: $e"; + rename $tmp, $photo or die "Cannot rename $tmp to $photo: $!\n"; + + print "... OK\n"; + $meta->{photo}->{$id} = $m; +} + +print "Writing meta-data\n"; +UCW::Gallery::WriteMeta($photo_meta, $meta); diff --git a/gal2/gal-scan b/gal2/gal-scan index 951a93c..39dd6b0 100755 --- a/gal2/gal-scan +++ b/gal2/gal-scan @@ -29,7 +29,7 @@ if (@ARGV) { my @p = (); while (my $e = readdir D) { my $f = File::Spec->canonpath(File::Spec->catfile($in, $e)); - if ($f =~ m{\.jpe?g$}i) { + if ($f =~ m{\.(jpe?g|png)$}i) { push @p, $f; } } -- 2.39.2