img: Correct bug in image size calculation code.
authorJoey Hess <joey@gnu.kitenet.net>
Mon, 28 Sep 2009 00:53:02 +0000 (20:53 -0400)
committerJoey Hess <joey@gnu.kitenet.net>
Mon, 28 Sep 2009 00:53:02 +0000 (20:53 -0400)
If an image was resized smaller, with width and height specified to values
that did not fit its aspect ratio, the image tag with/height were not
adjusted to the actual size imagemagick chooses.

This was broken by 03449610d6c666ba24bea68f01d896613e522278.

To fix it right, it unfortunatly needs to always read the src image now,
in order to determine if the image is being displayed larger, or resized
smaller. When resized smaller, it then always uses the size of the
thumbnail, while for larger it calculates the size.

(Only way to get rid of this sometimes extra image read would be to change
it to not allow displaying images larger.)

IkiWiki/Plugin/img.pm
debian/changelog

index 9ae85c4e682839d7a2179785e1c4e504d6ecc866..223b5a11f3e1250ae3dca43551f4601f47508894 100644 (file)
@@ -63,8 +63,9 @@ sub preprocess (@) {
        error gettext("Image::Magick is not installed") if $@;
        my $im = Image::Magick->new;
        my $imglink;
-       my $r;
-
+       my $r = $im->Read($srcfile);
+       error sprintf(gettext("failed to read %s: %s"), $file, $r) if $r;
+       
        my ($dwidth, $dheight);
 
        if ($params{size} ne 'full') {
@@ -74,69 +75,71 @@ sub preprocess (@) {
                error sprintf(gettext('wrong size format "%s" (should be WxH)'), $params{size})
                        unless (defined $w && defined $h &&
                                (length $w || length $h));
-
-               my $outfile = "$config{destdir}/$dir/${w}x${h}-$base";
-               $imglink = "$dir/${w}x${h}-$base";
                
-               will_render($params{page}, $imglink);
-
-               if (-e $outfile && (-M $srcfile >= -M $outfile)) {
-                       $r = $im->Read($outfile);
-                       error sprintf(gettext("failed to read %s: %s"), $outfile, $r) if $r;
+               if ((length $w && $w > $im->Get("width")) ||
+                   (length $h && $h > $im->Get("height"))) {
+                       # resizing larger
+                       $imglink = $file;
+
+                       # don't generate larger image, just set display size
+                       if (length $w && length $h) {
+                               ($dwidth, $dheight)=($w, $h);
+                       }
+                       # avoid division by zero on 0x0 image
+                       elsif ($im->Get("width") == 0 || $im->Get("height") == 0) {
+                               ($dwidth, $dheight)=(0, 0);
+                       }
+                       # calculate unspecified size from the other one, preserving
+                       # aspect ratio
+                       elsif (length $w) {
+                               $dwidth=$w;
+                               $dheight=$w / $im->Get("width") * $im->Get("height");
+                       }
+                       elsif (length $h) {
+                               $dheight=$h;
+                               $dwidth=$h / $im->Get("height") * $im->Get("width");
+                       }
                }
                else {
-                       $r = $im->Read($srcfile);
-                       error sprintf(gettext("failed to read %s: %s"), $file, $r) if $r;
-
-                       # don't resize any larger
-                       my ($rw, $rh) = ($w, $h);
-                       if ((length $rw && $rw > $im->Get("width")) ||
-                           (length $rh && $rh > $im->Get("height"))) {
-                               $rw=$im->Get("width");
-                               $rh=$im->Get("height");
-                       }
-
-                       $r = $im->Resize(geometry => "${rw}x${rh}");
-                       error sprintf(gettext("failed to resize: %s"), $r) if $r;
+                       # resizing smaller
+                       my $outfile = "$config{destdir}/$dir/${w}x${h}-$base";
+                       $imglink = "$dir/${w}x${h}-$base";
+               
+                       will_render($params{page}, $imglink);
 
-                       # don't actually write file in preview mode
-                       if (! $params{preview}) {
-                               my @blob = $im->ImageToBlob();
-                               writefile($imglink, $config{destdir}, $blob[0], 1);
+                       if (-e $outfile && (-M $srcfile >= -M $outfile)) {
+                               $im = Image::Magick->new;
+                               $r = $im->Read($outfile);
+                               error sprintf(gettext("failed to read %s: %s"), $outfile, $r) if $r;
+               
+                               $dwidth = $im->Get("width");
+                               $dheight = $im->Get("height");
                        }
                        else {
-                               $imglink = $file;
+                               ($dwidth, $dheight)=($w, $h);
+                               $r = $im->Resize(geometry => "${w}x${h}");
+                               error sprintf(gettext("failed to resize: %s"), $r) if $r;
+
+                               # don't actually write file in preview mode
+                               if (! $params{preview}) {
+                                       my @blob = $im->ImageToBlob();
+                                       writefile($imglink, $config{destdir}, $blob[0], 1);
+                               }
+                               else {
+                                       $imglink = $file;
+                               }
                        }
                }
-
-               # since we don't really resize larger, set the display
-               # size, so the browser can scale the image up if necessary
-               if (length $w && length $h) {
-                       ($dwidth, $dheight)=($w, $h);
-               }
-               # avoid division by zero on 0x0 image
-               elsif ($im->Get("width") == 0 || $im->Get("height") == 0) {
-                       ($dwidth, $dheight)=(0, 0);
-               }
-               # calculate unspecified size from the other one, preserving
-               # aspect ratio
-               elsif (length $w) {
-                       $dwidth=$w;
-                       $dheight=$w / $im->Get("width") * $im->Get("height");
-               }
-               elsif (length $h) {
-                       $dheight=$h;
-                       $dwidth=$h / $im->Get("height") * $im->Get("width");
-               }
-
        }
        else {
-               $r = $im->Read($srcfile);
-               error sprintf(gettext("failed to read %s: %s"), $file, $r) if $r;
                $imglink = $file;
                $dwidth = $im->Get("width");
                $dheight = $im->Get("height");
        }
+       
+       if (! defined($dwidth) || ! defined($dheight)) {
+               error sprintf(gettext("failed to determine size of image %s"), $file)
+       }
 
        my ($fileurl, $imgurl);
        if (! $params{preview}) {
@@ -148,10 +151,6 @@ sub preprocess (@) {
                $imgurl="$config{url}/$imglink";
        }
 
-       if (! defined($im->Get("width")) || ! defined($im->Get("height"))) {
-               error sprintf(gettext("failed to determine size of image %s"), $file)
-       }
-
        my $imgtag='<img src="'.$imgurl.
                '" width="'.$dwidth.
                '" height="'.$dheight.'"'.
index 2e27d623e86663ac43af95ad63e7b1a415b03b39..d2ff88a2ab2de6fb1561f0c5621c41da48dcb97e 100644 (file)
@@ -2,6 +2,7 @@ ikiwiki (3.14159266) UNRELEASED; urgency=low
 
   * parentlinks: Add has_parentlinks template parameter to allow styling
     the toplevel index differently etc.
+  * img: Correct bug in image size calculation code.
 
  -- Joey Hess <joeyh@debian.org>  Sun, 27 Sep 2009 17:40:03 -0400