Beefy Boxes and Bandwidth Generously Provided by pair Networks
more useful options
 
PerlMonks  

Using ImageMagick effectively

by Aldebaran (Curate)
on Sep 25, 2014 at 19:41 UTC ( [id://1102029]=perlquestion: print w/replies, xml ) Need Help??

Aldebaran has asked for the wisdom of the Perl Monks concerning the following question:

The topic of html templating seems to be trending. I'm always looking to increase what I can do with templates, and an important part of that for my needs is manipulating images. I want to be able to use perl for things that I might otherwise use a command line for, if nothing else than to spare the keystrokes as per the virtue of laziness. But it's essential for me not to have images that are 2 megs instead of 100 k, where most images do fine.

The first problem? I'm on a new machine, and every time I install ImageMagick, I feel like I'm getting hazed. What I think needs to happen is that perl has to be able to find the dev libraries, and somehow, what I have isn't doing that yet. According to my ubuntu 14.04 OS, I have this installed. Yet I can't get past the initial use. I took a couple screenshots and put them up on a page, which I created by commenting out the use statement: screenshots.

$ perl magick1.pl Can't locate Image/Magick.pm in @INC (you may need to install the Imag +e::Magick module) (@INC contains: template_stuff /etc/perl /usr/local +/lib/perl/5.18.2 /usr/local/share/perl/5.18.2 /usr/lib/perl5 /usr/sha +re/perl5 /usr/lib/perl/5.18 /usr/share/perl/5.18 /usr/local/lib/site_ +perl .) at magick1.pl line 15. BEGIN failed--compilation aborted at magick1.pl line 15. $

I don't want to get too ambitious for how much to get done on one thread, but after it's installed, I'd like to use perl to get all images in a directory shrunk to less than 100 k. Thanks for your comment.

Replies are listed 'Best First'.
Re: Using ImageMagick effectively
by Your Mother (Archbishop) on Sep 25, 2014 at 21:38 UTC

    Also consider GraphicsMagick. A nearly drop-in fork/replacement that is (supposedly) better and saner on the backend in most every way. I know ImageMagick has blown up on me a few times with memory or hanging and such for things that didn't seem reasonable (manipulating a few animated frames, I think). I have no installation advice.

Re: Using ImageMagick effectively
by Anonymous Monk on Sep 25, 2014 at 19:52 UTC
    According to my ubuntu 14.04 OS, I have this installed.

    Do you also have the perlmagick package (http://packages.ubuntu.com/trusty/perlmagick) installed? Is the perl in your PATH the system perl or a custom build?

      Installing perlmagick was what I needed. I've written a routine that iterates through the images folder, but I fail to create and assign the object correctly:

      sub resize_images { use 5.010; use Path::Class; use Image::Magick; my ($rvars) = shift; my %vars = %$rvars; opendir my $hh, $vars{to_images} or warn "warn $!\n"; while (defined ($_ = readdir($hh))){ my $image = Image::Magick->new; $image->ReadImage($_); $x = $image->Get('filesize'); say "$_ has filesize of $x"; } }

      Output:

      Screenshot from 2014-08-21 13:10:18.png has filesize of Screenshot from 2014-09-25 17:14:08.png has filesize of Screenshot from 2014-08-21 13:22:42.png has filesize of zbears.jpg has filesize of . has filesize of .. has filesize of yjj.jpg has filesize of

      Fishing for tips....

        You need to prepend the directory to the filename (see readdir), and you can check if the read was successful:
        my $dir = $vars{to_images}; ... my $err = $image->ReadImage("$dir/$_"); warn "$err" if $err;
        Also, might be better to filter out the non-image files before passing to Image::Magick.
Re: Using ImageMagick effectively
by trippledubs (Deacon) on Sep 26, 2014 at 00:06 UTC
    bash# for i in *jpg; do convert "$i" -resize '800x600' "resize-${i}"; +done
    Alternate solution using the command line. Put an ampersand at the end and you can start scripting while it is converting in the background.
      /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"; } }

        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 $
Re: How to install ImageMagick module ( Can't locate Image/Magick.pm in @INC (you may need to install the Image::Magick module)
by Anonymous Monk on Sep 26, 2014 at 01:10 UTC

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://1102029]
Approved by GotToBTru
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-19 12:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found