Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

graphicsmagick perl shrink image to size

by melutovich (Acolyte)
on Nov 01, 2021 at 12:42 UTC ( [id://11138293]=perlquestion: print w/replies, xml ) Need Help??

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

the graphicsmagick package for perl is very extensive but the documentation appears light (or confusing to me) If I have an image and I want to ensure the size is within 800x200 (like https://via.placeholder.com/800x200) while maintaining the aspect ratio of the image, which commands should I use?
  • Comment on graphicsmagick perl shrink image to size

Replies are listed 'Best First'.
Re: graphicsmagick perl shrink image to size
by bliako (Monsignor) on Nov 01, 2021 at 18:12 UTC

    I managed to install this package via my linux package manager along with the library.

    Here is something to get you started from first principles:

    #!/usr/bin/perl # by bliako # for https://perlmonks.org/?node_id=11138293 # on 01/11/2021 use strict; use warnings; use Graphics::Magick; my($image, $status); $image = Graphics::Magick->new; $status = $image->Read('a.jpg'); my $W = $image->Get('width'); my $H = $image->Get('height'); my $maxW = 800; my $maxH = 200; my ($newW, $newH, $factor) = trans($W, $H, $maxW, $maxH); my $AR = $W / $H; my $newAR = $newW / $newH; print "($W x $H) => ($newW x $newH)\n"; print "original aspect ratio: $AR, new aspect ratio:$newAR\n"; $image->Resize(width => $newW, height => $newH); $image->write("resized.jpg"); #testme(); # given original dimensions and new max dimensions # it returns (newW, newH, resize_factor) sub trans { my ($W, $H, $maxW, $maxH) = @_; my ($arW, $arH); my $factor = ($arW=($W/$maxW)) < ($arH=($H/$maxH)) ? $arH : $arW; my $newW = int($W/$factor); my $newH = int($H/$factor); return ($newW, $newH, $factor); } # this does a brute-force testing on sizes 10-1000 # for 800x200 max dim sub testme { my $maxW = 800; my $maxH = 200; for my $W (map { $_*10 } 1..100){ for my $H (map { $_*10 } 1..100){ my ($newW, $newH, $factor) = trans($W, $H, $maxW, $maxH); my $AR = $W / $H; my $newAR = $newW / $newH; die "failed test: aspect ratios not the same ($AR -> $newAR) for + ($W x $H) => ($newW x $newH)" if ($AR-$newAR) > 10E-1; die "failed test: new width exceeds maximum for ($W x $H) => ($n +ewW x $newH)" if $newW > $maxW; die "failed test: new height ($newH) exceeds maximum for ($W x $ +H) => ($newW x $newH)" if $newH > $maxH; } } }

    Output:

    (2560 x 1536) => (333 x 200) original aspect ratio: 1.66666666666667, new aspect ratio:1.665

    bw, bliako

Re: graphicsmagick perl shrink image to size
by tangent (Parson) on Nov 01, 2021 at 17:00 UTC
    I gave up using Image Magick in favour of Imager. If you have a look at the scale() function on the Imager::Transformations page you will see how easy it is to accomplish.
    my $newimg = $img->scale( xpixels => 800, ypixels => 200, type => 'min', );
    Obviously you only need to do this transform if the original image exceeds one of the dimensions.
Re: graphicsmagick perl shrink image to size
by perlfan (Vicar) on Nov 01, 2021 at 16:26 UTC
    I've never heard of graphicsmagick - forked from ImageMagick in 2002, nice! I guess they provide the standard convert command? If so, the first step is figuring that out. I use Image/PerlMagick myself for some things, but I have to study the docs any time I really need to do something. But anything you can do at the commandline (convert) should translate conceptially to the Perl API, and in fact that's what I do usually - get it working in the CLI then translate it over to the Perl using what I've learned.
      I used convert a lot in the past and at the beginning I always felt dumb when thing didn't go like documented.

      Then I realized that the tool is a Frankenstein'ish monster of various incompatible tools for different formats sewed together.

      The docs are accordingly a Babylonian mishmash where different terminologies mix and getting things done require a lot of try and error.

      Perl modules providing a wrapper can only attempt to compensate this.

      Cheers Rolf
      (addicted to the Perl Programming Language :)
      Wikisyntax for the Monastery

        > Babylonian Frankenstein'ish monster

        No doubt, sounds like why it's spelled magick with an icK :-)

      forked from ImageMagick in 2002

      ... but still does use the braindead ImageMagick way of NOT raising errors, but instead returning error codes. Shouldn't have been too hard to fix that after forking. (See also Re^2: Pixel setting oddity - Image:Magick, Re^7: Use of uninitialized value $pic)

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)
Re: graphicsmagick perl shrink image to size
by choroba (Cardinal) on Nov 01, 2021 at 15:15 UTC
    Can you link to the package on CPAN? Both my guesses Graphics::Magick and GraphicsMagick come up empty.

    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: graphicsmagick perl shrink image to size
by karlgoethebier (Abbot) on Nov 02, 2021 at 06:28 UTC

    See here for a command line alternative. Or here for a cheap GUI. See also for a solution for free. Less or more all the stuff i mentioned is scriptable/capable for batch processing etc. I forgot the ugly details.

    «The Crux of the Biscuit is the Apostrophe»

Re: graphicsmagick perl shrink image to size
by kcott (Archbishop) on Nov 01, 2021 at 15:20 UTC

        G'day Bod,

        You're welcome.

        To be honest, except for links within this site (e.g. [id://11123653|Bod] above; and [id://43036] for the shortcuts links I posted), and very basic external URLs (e.g. [URL]), I rarely use those shortcuts.

        I normally check the webpage and section first; my guesses are generally good but I'm not infallible. When writing up my post, I'll type "["; Alt-Tab to the webpage and copy the address bar; Alt-Tab again and paste; type "|"; Alt-Tab again and copy the title; Alt-Tab again and paste; type "]" and I'm done.

        This potentially seems like a lot of work but, with over a decade of muscle memory at my fingertips, this is a two second task. Furthermore, I'll never provide a link to splice labelled split, or vice versa, again.

        — Ken

Re: graphicsmagick perl shrink image to size
by cavac (Parson) on Nov 04, 2021 at 11:52 UTC

    I used ImageMagick based stuff for a long time. But i switched to GD for most of my stuff, because it also allows for easy acceptable pixel manipulation, even if it's painfully slow.

    The basic calculation to calculate the new image dimension goes something like this, no matter which image manipulation module you end up using (from memory, untested):

    # Check if we are limited by height or width of the source image my $factor = $sourcewidth / $targetwidth; if($sourceheight / $factor > $targetheight) { $factor = $sourceheight / $targetheight; ) my $newwidth = int($sourcewidth / $factor); my $newheight = int($sourceheight / $factor);

    You can then, for example, use the copyResized method from GD:

    $newpic->copyResized($sourcepic, $destx, $desty, # DEST X Y 0, 0, # SRC X Y $newwidth, $newheight, # DEST W H $sourcewidth, $sourceheight, # SRC W H );

    It's also worth noting that there might be a lot more pixel massaging needed to be done, depending on what those resulting images are used for. For example, i have a use case where i have to print user provided logos onto thermal paper. I ended up having to implement multiple algorithms for transforming color images to black&white pixels from which the user can select. Here is the printAddGreyscaleImage() from my PageCamel Framework PrintProcessor.pm:

    Dithering by pixel manipulation is painfully slow (it can take multiple seconds per logo). But the software usually runs for days on end and has only a few different logos to deal with, so i did a simple in-memory caching. Once the system is up and running for a few minutes, no more slowdown.

    perl -e 'use Crypt::Digest::SHA256 qw[sha256_hex]; print substr(sha256_hex("the Answer To Life, The Universe And Everything"), 6, 2), "\n";'

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (5)
As of 2024-04-25 12:23 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found