in reply to Re: Using ImageMagick effectively
in thread Using ImageMagick effectively

/home/fred/Desktop/root3/pages/giants/template_stuff/aimages/Screensho +t from 2014-08-21 13:10:18.png has filesize of 250625 bytes or 244.75 +09765625 k file is /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/S +creenshot from 2014-08-21 13:10:18.png ratio is 2.39951937806373 /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/Screensho +t from 2014-09-25 17:14:08.png has filesize of 166140 bytes or 162.24 +609375 k file is /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/S +creenshot from 2014-09-25 17:14:08.png ratio is 1.59064797794118 /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/Screensho +t from 2014-08-21 13:22:42.png has filesize of 81126 bytes or 79.2246 +09375 k /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/zbears.jp +g has filesize of 872877 bytes or 852.4189453125 k file is /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/z +bears.jpg ratio is 8.35704848345588 /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/. has fil +esize of bytes or 0 k /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/.. has fi +lesize of bytes or 0 k /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/yjj.jpg h +as filesize of 237182 bytes or 231.623046875 k file is /home/fred/Desktop/root3/pages/giants/template_stuff/aimages/y +jj.jpg ratio is 2.27081418504902

I'm pretty close on this one now. I know by what amount I want to reduce filesizes to. The syntax I relied on doing it bash style was a percentage. I'm still looking for that option. For what I'm doing right now, I don't want to bias the shapes of the things I post. I handle their shapes with the css. This is what I have now:

sub resize_images { use 5.010; use Path::Class; use Image::Magick; my ($rvars) = shift; my %vars = %$rvars; $target = 100; $bias = 2; opendir my $hh, $vars{to_images} or warn "warn $!\n"; while (defined ($_ = readdir($hh))){ my $image = Image::Magick->new; my $file = file($vars{to_images},$_); $image->ReadImage($file); $x = $image->Get('filesize'); my $k = $x/1024; say "$file has filesize of $x bytes or $k k"; if ($k>$target){ say "file is $file"; my $ratio = $k/($target+$bias); say "ratio is $ratio"; } }

Replies are listed 'Best First'.
Re^3: Using ImageMagick effectively
by Aldebaran (Curate) on Sep 27, 2014 at 04:16 UTC

    It looks like the only way to use resize is to use the command line. I don't know how to make that happen with perl driving the logic other than through a system command followed by some script you've written. That's what I attempt to do here, but I seem to be hung up on a printf statement. Why is the %s not working in this printf call? I can see on my terminal that the loop is loading all the images in the directory, and that the logic for entering into the inner control seems to work, that is filesizes less than the target value are ignored, which gets rid of . and .. too. What follows is the routine followed by the helper script it creates.

    sub resize_images { use 5.010; use Path::Class; use Image::Magick; my ($rvars) = shift; my %vars = %$rvars; $vars{"target"}= 100; $vars{"bias"}= 2; $vars{"helpscript"}= "helper1.sh"; my $file2 = $vars{"helpscript"}; my $path = $vars{"to_images"}; open( my $fh, ">", $file2 ) or die("Can't open $file2 for writing: $!"); my $cd = "cd $path \n"; print $fh $cd; my $ls = "ls -lt >>text1.txt\n"; print $fh $ls; opendir my $hh, $path or warn "warn $!\n"; while (defined ($_ = readdir($hh))){ my $image = Image::Magick->new; my $file = file($path,$_); $image->ReadImage($file); $x = $image->Get('filesize'); my $k = $x/1024; say "$file has filesize of $x bytes or $k k"; if ($k>$vars{"target"}){ say "file is $file"; my $ratio = $k/($vars{"target"}-$vars{"bias"}); say "ratio is $ratio"; my $percent = 100/$ratio; say "percent is $percent"; my $mogrify_spec = "mogrify -resize %2.2f\% %s\n"; printf $fh $mogrify_spec, $percent, $file; #printf $fh "file is $file\n"; } close $fh; } }
    $ cat helper1.sh cd /home/fred/Desktop/root3/pages/raiders/template_stuff/aimages ls -lt >>text1.txt mogrify -resize 40.04%s $

      The "\%" in your $mogrify_spec isn't doing what you think - it results in the format string containing a "%". Even if you put a backslash in the string via "\\", that's not what you want:

      $ perl -wMstrict -e 'print "foo %2.2f\% %s\n"' foo %2.2f% %s $ perl -wMstrict -e 'printf "foo %2.2f\% %s\n", 40.04, "bar"' foo 40.04%s $ perl -wMstrict -e 'print "foo %2.2f\\% %s\n"' foo %2.2f\% %s $ perl -wMstrict -e 'printf "foo %2.2f\\% %s\n", 40.04, "bar"' foo 40.04\%s

      See sprintf: The way to escape a percent sign in a format string is "%%":

      $ perl -wMstrict -e 'print "foo %2.2f%% %s\n"' foo %2.2f%% %s $ perl -wMstrict -e 'printf "foo %2.2f%% %s\n", 40.04, "bar"' foo 40.04% bar

      (I'm a little surprised Perl doesn't warn about this, because there are several other warnings about bad format strings and such...)

        Ok, good, I made sprintf its own statement and dropped the printf altogether. I think the common advice is to use printf only when you have to. I get partial results from this now. It does resize the jpgs but I think it has problems with spaces in the names of files, which doesn't sound unusual on a command line. First, the subroutine:

        sub resize_images { use 5.010; use Path::Class; use Image::Magick; my ($rvars) = shift; my %vars = %$rvars; $vars{"target"}= 100; $vars{"bias"}= 2; $vars{"helpscript"}= "helper1.sh"; my $file2 = $vars{"helpscript"}; my $path = $vars{"to_images"}; open( my $fh, ">", $file2 ) or die("Can't open $file2 for writing: $!"); my $cd = "cd $path \n"; print $fh $cd; my $ls1 = "ls -lht >>text1.txt\n"; print $fh $ls1; opendir my $hh, $path or warn "warn $!\n"; while (defined ($_ = readdir($hh))){ my $image = Image::Magick->new; my $file = file($path,$_); $image->ReadImage($file); $x = $image->Get('filesize'); my $k = $x/1024; say "$file has filesize of $x bytes or $k k"; if ($k>$vars{"target"}){ say "file is $file"; my $ratio = $k/($vars{"target"}-$vars{"bias"}); say "ratio is $ratio"; my $percent = 100/$ratio; say "percent is $percent"; my $trim= sprintf("%3.2f", $percent); say "default is $_"; my $mogrify = "mogrify -resize $trim% $file\n"; print $fh $mogrify; } } my $ls2 = "ls -lht >>text2.txt\n"; print $fh $ls2; close $fh; ## system call my $system = 'bash helper1.sh'; my $return = system( $system ); return $return; }

        The output was hard for me to believe, but I don't think my computer is lying to me. html output The thing that jumps out is how a jpg of size 853 becomes 17k after a resize that should have landed it at 98k. But it's definitely a washed-out image. This is what the ls commands and the helper script look like:

        $ pwd /home/fred/Desktop/root3/pages/baylor/template_stuff/aimages $ cat text1.txt total 1.6M -rw-rw-r-- 1 fred fred 0 Sep 27 17:17 text1.txt -rw-rw-r-- 1 fred fred 232K Sep 27 17:14 yjj.jpg -rw-rw-r-- 1 fred fred 853K Sep 27 17:14 zbears.jpg -rw-rw-r-- 1 fred fred 80K Sep 27 17:14 Screenshot from 2014-08-21 13 +:22:42.png -rw-rw-r-- 1 fred fred 163K Sep 27 17:14 Screenshot from 2014-09-25 17 +:14:08.png -rw-rw-r-- 1 fred fred 245K Sep 27 17:14 Screenshot from 2014-08-21 13 +:10:18.png $ cat text2.txt total 568K -rw-rw-r-- 1 fred fred 0 Sep 27 17:17 text2.txt -rw-rw-r-- 1 fred fred 50K Sep 27 17:17 yjj.jpg -rw-rw-r-- 1 fred fred 17K Sep 27 17:17 zbears.jpg -rw-rw-r-- 1 fred fred 406 Sep 27 17:17 text1.txt -rw-rw-r-- 1 fred fred 80K Sep 27 17:14 Screenshot from 2014-08-21 13 +:22:42.png -rw-rw-r-- 1 fred fred 163K Sep 27 17:14 Screenshot from 2014-09-25 17 +:14:08.png -rw-rw-r-- 1 fred fred 245K Sep 27 17:14 Screenshot from 2014-08-21 13 +:10:18.png $ cd .. $ cd .. $ cat helper1.sh cd /home/fred/Desktop/root3/pages/baylor/template_stuff/aimages ls -lht >>text1.txt mogrify -resize 40.04% /home/fred/Desktop/root3/pages/baylor/template_ +stuff/aimages/Screenshot from 2014-08-21 13:10:18.png mogrify -resize 60.40% /home/fred/Desktop/root3/pages/baylor/template_ +stuff/aimages/Screenshot from 2014-09-25 17:14:08.png mogrify -resize 11.50% /home/fred/Desktop/root3/pages/baylor/template_ +stuff/aimages/zbears.jpg mogrify -resize 42.31% /home/fred/Desktop/root3/pages/baylor/template_ +stuff/aimages/yjj.jpg ls -lht >>text2.txt $

        How do I write this script so that perl knows it exited successfully? stdout has the details, and I liked the calculations that were going to land these images at the desired sizes. Clearly, I need to poke around with other numbers for resize.

        So I'm at the point where I'm wondering about the tool chain. As I said in the original post, working up an ImageMagick capability feels like being hazed, but it's all about honing the tools. I don't think I want to use mogrify, because that's gonna stomp all over my image in round one. Furthermore, I want to compare results when I use differing scaling schemas. The only thing significant about the image names is their extension and their lexicographic order relative to each other, as this determines their order. Is there a module for coming up with arbitrary filenames which are guaranteed to be well-behaved?

      It looks like the only way to use resize is to use the command line.

      The following works for me. The API is documented here: http://www.imagemagick.org/script/perl-magick.php

      use Image::Magick; my $img = Image::Magick->new; my $rv = $img->Read('/tmp/foo.jpg'); die "$rv" if "$rv"; $rv = $img->Resize(geometry=>'50%'); die "$rv" if "$rv"; $rv = $img->Write('/tmp/bar.jpg'); die "$rv" if "$rv";