chiark / gitweb /
mason/{.perl-lib/TrivGal,dhandler}: Make an image object.
authorMark Wooding <mdw@distorted.org.uk>
Fri, 24 Dec 2021 17:28:03 +0000 (17:28 +0000)
committerMark Wooding <mdw@distorted.org.uk>
Sat, 25 Dec 2021 16:09:18 +0000 (16:09 +0000)
The objective here is to separate image loading from scaling, so that we
can make several scaled output images without having to load and decode
the original image each time.

The `.thumbnail' module now takes an image object rather than a
pathname.  There's no functional change.

mason/.perl-lib/TrivGal.pm
mason/dhandler

index 9822a0bd2f10effaa890cd9e9861d3356ad038eb..838de976ae71ed160e709e1db6f90884f8bfe22d 100644 (file)
@@ -29,7 +29,6 @@ use autodie qw{:all};
 
 use Errno;
 use Exporter qw{import};
-use File::Path qw{make_path};
 use File::stat;
 use Image::Imlib2;
 use User::pwent;
@@ -183,35 +182,55 @@ sub clean_temp_files () {
 ###--------------------------------------------------------------------------
 ### Scaled images.
 
-export qw{scaled};
-sub scaled ($$) {
-  my ($scale, $path) = @_;
-
-  my $sz = $SIZE{$scale} or die "unknown scale `$scale'";
-  my $imgpath = "$IMGROOT/$path";
-  my $ist = stat $imgpath or die "no image `$path'";
-  my $thumb = "$CACHE/scaled.$scale/$path";
-  my $thumburl = "$CACHEURL/scaled.$scale/$path";
-  my $tst = stat $thumb;
-  if (defined $tst && $tst->mtime > $ist->mtime) { return $thumburl; }
-  my ($dir, $base, $ext) = split_path $thumb;
-  my $ty = $TYPE{lc $ext} or die "unknown type `$ext'";
-
-  my $img = Image::Imlib2->load($imgpath);
-  my ($wd, $ht) = ($img->width, $img->height);
-  my $max = $wd > $ht ? $wd : $ht;
-  if ($max <= $sz) { return "$IMGURL/$path"; }
-  my $sc = $sz/$max;
-  my $scaled = $img->create_scaled_image($sc*$wd, $sc*$ht);
-
-  $scaled->image_set_format($ty->imlibfmt);
-  $scaled->set_quality(90);
-  my $new = "$TMP/t${$}$ext";
-  make_path $TMP;
-  $scaled->save($new);
-  make_path $dir;
-  rename $new, $thumb;
-  return $thumburl;
+package TrivGal::Image {
+  use File::Path qw{make_path};
+  use File::stat;
+
+  sub new ($$) {
+    my ($cls, $path) = @_;
+    my $imgpath = "$IMGROOT/$path";
+    my $st = stat $imgpath or die "no image `$path'";
+    return bless {
+      path => $path,
+      mtime => $st->mtime,
+      img => undef
+    }, $cls;
+  }
+
+  sub scale ($$) {
+    my ($me, $scale) = @_;
+
+    my $path = $me->{path};
+    my $sz = $SIZE{$scale} or die "unknown scale `$scale'";
+    my $thumb = "$CACHE/scale.$sz/$path";
+    my $thumburl = "$CACHEURL/scale.$sz/$path";
+    my $st = stat $thumb;
+    if (defined $st && $st->mtime > $me->{mtime}) { return $thumburl; }
+
+    my ($dir, $base, $ext) = TrivGal::split_path $thumb;
+    my $ty = $TYPE{lc $ext} or die "unknown type `$ext'";
+
+    my $img = $me->{img};
+    unless (defined $img) {
+      my $imgpath = "$IMGROOT/$path";
+      $img = $me->{img} = Image::Imlib2->load($imgpath);
+    }
+
+    my ($wd, $ht) = ($img->width, $img->height);
+    my $max = $wd > $ht ? $wd : $ht;
+    if ($max <= $sz) { return "$IMGURL/$path"; }
+    my $sc = $sz/$max;
+    my $scaled = $img->create_scaled_image($sc*$wd, $sc*$ht);
+
+    $scaled->image_set_format($ty->imlibfmt);
+    $scaled->set_quality(90);
+    my $new = "$TMP/t${$}$ext";
+    make_path $TMP;
+    $scaled->save($new);
+    make_path $dir;
+    rename $new, $thumb;
+    return $thumburl;
+  }
 }
 
 ###--------------------------------------------------------------------------
index 44a9cebe9de18ccf766cdef297f8d51f99a23b85..7d76fdf80a85267a3fb73331c481cb58c530b1d4 100755 (executable)
@@ -100,9 +100,9 @@ Failed to find &lsquo;<% $path |h %>&rsquo;.
 <div class=gallery>
 %   for my $d (@$dd) {
 %     my ($ddd, $fff, $iii) = listdir $real . "/" . $d->name;
-%     my $tn;
-%     if ($iii) { $tn = join_paths $path, $d->name, $iii->name; }
-%     else { $tn = undef; }
+%     my $tn = $iii ?
+%      TrivGal::Image->new(join_paths $path, $d->name, $iii->name) :
+%       undef;
   <& .thumbnail, target => $d->name . "/", comment => $d->comment,
                 img => $tn, size => "bigthumb",
                 caption => $m->interp->apply_escapes($d->name, "h") &>\
@@ -115,7 +115,8 @@ Failed to find &lsquo;<% $path |h %>&rsquo;.
 <div class=gallery>
 %   for my $f (@$ff) {
   <& .thumbnail, target => $f->name, comment => $f->comment,
-                img => $path . $f->name, size => "bigthumb",
+                img => TrivGal::Image->new($path . $f->name),
+                size => "bigthumb",
                 caption => $m->interp->apply_escapes($f->name, "h") &>\
 %   }
 </div>
@@ -139,7 +140,7 @@ Failed to find &lsquo;<% $path |h %>&rsquo;.
        my $realdir = join_paths $IMGROOT, $dir;
        my $urldir = join_paths $SCRIPTURL, $dir;
        my ($dd, $ff, $ii) = listdir $realdir;
-       my $vw = scaled "view", $path;
+       my $vw = TrivGal::Image->new($path)->scale("view");
 
        my $fi = undef;
        FILE: for (my $i = 0; $i < @$ff; $i++)
@@ -191,7 +192,7 @@ Failed to find &lsquo;<% $path |h %>&rsquo;.
 %
 <div class=thumbstrip>
 % for my $f (@$ff) {
-%   my $img = $dir . "/" . $f->name;
+%   my $img = TrivGal::Image->new($dir . "/" . $f->name);
   <& .thumbnail, target => $f->name, img => $img, size => "bigthumb",
                 caption => $m->interp->apply_escapes($f->name, "h"),
                 focus => $f->name eq "$base$ext" &>\
@@ -236,7 +237,7 @@ Failed to find &lsquo;<% $path |h %>&rsquo;.
 %###-------------------------------------------------------------------------
 <%def .thumbnail>\
 % my $tn;
-% if (defined $img) { $tn = scaled $size, $img; }
+% if (defined $img) { $tn = $img->scale($size); }
 % else { $tn = "$STATICURL/folder.svg"; }
 % if ($focus) {
   <figure class="thumb <% $size %>" id=focusthumb>