Resizing images with phMagick

August 9, 2009 by nuno costa 19 comments

phMagick :: Resizing Images

By default phMagick will resize images if they are bigger than the specified measures because enlarging images always produces bad results (heavily pixelized images).

Proportional width & height resize

If you just specify one measure the image will be resized proportionally to the desired size

To 200px width :

//resing to fit a particuar width
$phMagick = new phMagick('lipe.jpg', 'resize_porp_w.png');
$phMagick->resize(200); // the same as resize(200,0)

 

Original Image Transformed Image
resized to 200px width

 

 

To 100px height :

// and to fit a particular height
$phMagick = new phMagick('lipe.jpg');
$phMagick->setDestination('resize_porp_h.png')
 ->resize(0,100); 
// set width to 0 so that phMagick knows that the resize should 
// be done proportional to the height of the image
 
// We can set the destination file name in the class instantiation or by 
// using the setDestination() function

 

 

Original Image Transformed Image
resized to 100px height

 

 

 

Resizing to fit in a box

If you specify width and height the image will be resized to a size that bests fits the measures, it may not be the exact measures since aspect ratio will be maintained. If you set ExactSize = true then no attempt to maintain aspect ratio will be done and the image will have exactly the measures specified

Mantaining aspect ration

//fitting a 150x 100px box
$phMagick = new phMagick('lipe.jpg');
$phMagick->setDestination('resize_porp_wh.png')
 ->resize(150,100);

 

Original Image Transformed Image
Resized to fit a box

 

 

Exact dimensions

// making it exactly 80 x 150px
$phMagick = new phMagick('lipe.jpg');
$phMagick->setDestination('resize_dumb.png')
 ->resize(80,150,true);

 

Original Image Transformed Image

Resized to exact dimentions

 

As you can see resizing to an exact size may produce streched images

 

Resize an image to an exact size mantaining aspec ratio

It's possible to resize an image to an exact size while mantaining the aspect ratio, internaly this is done by resising and croping the new image

Take note that this aproach is not 100% accurate, there are some extreme situations where the resulting image will not have the desired size

 

$p = new phmagick('source.png', 'destination.png');
$p->resizeExactly(133,100);
Original Image Transformed Image
resized to 100px height

19 comments so far Add Your Comment

  1. by Leonardo Cesar Teixeira on October 10 2009 at 16:30

    Olá Franco,

    Parabéns pela classe phMagick, ela é realmente fantástica.

    Eu estava procurando alguma coisa na internet pra servir de base pra eu montar uma classe própria, mas achei a sua tão completa que acho que vou usar ela própria.

    Eu só estou com um problema pra redimensionar imagens GIF com animação, elas ficam zoadas.

    Você sabe como resolver isso ou a sua classe ainda não dá suporte para animações?

    Pois preciso exatamente disso, inclusive é o motivo de eu não utilizar a classe Imagick que é nativa do PHP.

    Eu tentei da seguinte forma:


    require(dirname(__FILE__) . '/phmagick.php');

    $img = new phMagick('animacao.gif');
    $img->setDestination('saida_animacao.gif')->resize(250, 250);

    Abraços!

  2. by nuno costa on October 10 2009 at 23:06

    Olá Leonardo,

    Pois o ImageMagick não é grande coisa a redimensionar gifs animados, pelo que li é preciso fazer primeiro um coalesce à imagem

    convert animatef.gif -coalesce coalesce.gif

    e depois então fazer o resize

    um abraço

  3. by Joseph on March 7 2010 at 22:21

    Hello Nuno. Firstly the phmagick package is excellent and very useful (and given me some good ideas on using plugin classes). Thankyou!

    I had a problem with the polaroid and reflection methods when altering an image already altered using the crop class. The polaroid image shifted partly off the canvas so it was only partly visible, the reflected image was only a portion of the width of the original.

    Long story short, after some tinkering I replaced the following

    $cmd .= ‘ ‘ . $p->getDestination() ;

    with

    $cmd .= ‘ +repage ‘ . $p->getDestination() ;

    in phMagick_crop::crop wich seemd to work like a charm.

    I thought you may find it useful (although I haven’t fully tested that it doesn’t break anything else, my fixes usually do!)

  4. by Francesco on March 19 2010 at 19:46

    Ciao. Se per te non è un problema crea una reindirizzo poichè in Internet tutti i link fanno riferimento a:
    http://www.francodacosta.com/phmagick
    Ho penato non poco… anche alcuni link di questo blog sn errati!!
    PS… Grande Lavoro!!!

  5. by swiss on May 1 2010 at 08:53

    hi,

    Is it possible to use cache directory.Instead of resizing everytime.converting takes some cpu resources..

  6. by nuno costa on May 22 2010 at 17:16

    @swiss

    the onTheFly() function does that, only resizes an image if it was not resized before

  7. by sean on June 9 2010 at 17:33

    Is it possible to use onTheFly with resizeExactly??

    I am having a few trouble and exactDimentions stretches the image when set to True, I have tried using the, using the resizeExactly function instead of the resize but this does not seem to create the desired image?

    Has anyone else been able to achieve this?

    Thanks

  8. by nuno costa on June 10 2010 at 21:34

    I don’t think it’s possible

    onthefly works with urls and resizeexacly with file paths

    although it is really easy to implement the onthefly functionality with resize exacly as it checks if the file destination exists, if exists then use that file and do not create a new one

    the exactDimentions is something different, it will resize the image to that exact dimensions ignoring aspect ratio

    hope this helps you, if nt just mail me and I will try to help you

  9. by sean on June 11 2010 at 13:28

    Thank you Nuno,
    That clears things up

    I decided to check the destination first and then use the resizeExactly function if the image did not exist. This solves my problem, as I did not want the image to be created every time the page was loaded.

  10. by Christian on August 5 2010 at 10:36

    Dear Nuno,

    thank you very much for this superb PHP class! It works like a charm! But I do have a question: In all your examples there is always a source and a destination-file.

    Is it also possible for phmagick to to resize an image live, so that the picture is just simply stored in the memory while the user is watching the file?

    The thing is i’d like to resize my original images “live” while the user watches them. But the original file should be left untouched and i also don’t need any thumbs. I remember that there was a function for that in GD Lib of PHP. Afterwards this this picture was deleted with a function called “imagedestroy();”.

    Is that also possible with phmagick?

    Thanks in advance!

    Regards Christian

  11. by nuno costa on August 23 2010 at 19:45

    Unfortunately no

    phMagick runs ImageMagick from the command line, so it needs a source and destination files (they can be the same)

    you can implement something similar using a temporary file name and overwriting it on each change

    I will see if I can implement a preview mode in phMagick, but I’m very busy now

  12. by bjn on September 7 2010 at 13:20

    I think you may have an error in your docs — in “resize to fit in a box” you say “fit a 150×150 box” but then have “resize(150,100)”.

  13. by nuno costa on November 1 2010 at 08:02

    @bjn,

    thanks

  14. by phil k on November 9 2010 at 00:52

    i’m currently using GD for dynamic image resizing and am disappointed w the quality of the end results due to compression. your tool seems like it would be a good solution, however the resizeExact function is very quick to produce images with a different final size than requested. is there any way to force the size even if it means the image has to be cropped more?

    real world example: 357px × 288px -> 320 x 240px

    GD handles this fine through this code that i cobbled together below(however the resultant image is over compressed). is there a way to determine a fixed image size regardless of how much cropping is required?

    if ($imgsize[0]>$imgsize[1])
    {
    $new_height=$target_width/$imgsize[0]*$imgsize[1];
    imagecopyresampled($resized_img,$new_img, 0, 0, 0, 0, $target_width ,$new_height, $imgsize[0], $imgsize[1]);
    }
    else
    {

    $target_width ,$new_height, $imgsize[0], $imgsize[1]);

    $new_width=$target_height/$imgsize[1]*$imgsize[0];
    $margin=($target_width-$new_width)/2;
    imagecopyresampled($resized_img,$new_img, $margin, 0, 0, 0, $new_width ,$target_height, $imgsize[0], $imgsize[1]);

    }

  15. by S.Muthu Pandi on May 27 2011 at 11:03

    hi nuno…

    Am trying to resize image using this script. I got this error message.

    phMagick: Error executing “convert -scale “200x>” -quality 80 -strip “http://vibrantproxy/testproject/muthu/resize/Cherry-on-Top.jpeg” “http://vibrantproxy/currentproject/sweetdeal/banner_image/test2.jpeg”"
    return code: 1
    command output :”convert: no data returned `http://vibrantproxy/testproject/muthu/resize/Cherry-on-Top.jpeg’.
    convert: missing an image filename `http://vibrantproxy/currentproject/sweetdeal/banner_image/test2.jpeg’.”
    Notice: exception ‘phMagickException’ in /opt/lampp/htdocs/testproject/muthu/resize/phmagick.php:189 Stack trace: #0 /opt/lampp/htdocs/testproject/muthu/resize/plugins/resize.php(47): phmagick->execute(‘convert -scale …’) #1 [internal function]: phMagick_resize->resize(Object(phmagick), 200) #2 /opt/lampp/htdocs/testproject/muthu/resize/phmagick.php(205): call_user_func_array(Array, Array) #3 [internal function]: phmagick->__call(‘resize’, Array) #4 /opt/lampp/htdocs/testproject/muthu/resize/sample.php(4): phmagick->resize(200) #5 {main} in /opt/lampp/htdocs/testproject/muthu/resize/phmagick.php on line 189
    1

    How to solve this error?

    this is my script.

    resize(200);
    ?>

  16. by Christopher Robinson on June 8 2011 at 22:54

    I added this method to the plugin to allow for exact resizing without cropping (instead it pads the difference with a background color of your choice). Hope it helps someone out.

    /**
    * tries to resize an image to the exact size wile mantaining aspect ratio,
    * the image will be padded with background color to fit the measures
    * @param $width
    * @param $height
    * @param $background
    */
    function resizeExactlyNoCrop(phmagick $p, $width, $height, $background=’#FFFFFF’)
    {
    $cmd = $p->getBinary(‘montage’);
    $cmd .= ‘ -background ‘ . $background;
    $cmd .= ‘ -geometry ‘. $width .’x’. $height;
    $cmd .= ‘ “‘ . $p->getSource() .’” “‘. $p->getDestination().’”‘;
    $p->execute($cmd);
    $p->setSource($p->getDestination());
    $p->setHistory($p->getDestination());
    return $p;
    }

  17. by nuno costa on August 1 2011 at 20:50

    thanks

  18. by Megaten on January 15 2012 at 12:43

    Hello nuno,
    After a long seeking, checking, I arrived thru your script to acces to the ImageImagick and with succes.
    But there is often a ‘but’, I wouls like to use imagick to preserve the exif data during a convert.
    So, I don’t know if I’ve done a miss due to my inexperience… or if that is not possible.
    Thanks for your support and comments

    Following my sample
    include(‘phMagick.php’);
    echo “Start”;
    echo ‘ ‘;
    $img = new phMagick(‘Tests.jpg’);
    $img->setDestination(‘TestsO.jpg’)->resize(900, 600);
    echo ‘ ‘;
    echo ‘End Resize ‘;

  19. by Megaten on January 16 2012 at 19:22

    Ok I have found the trouble.
    There a ‘strip’ into the script resize.php, without that it’s ok
    See you a next time and thak you for your project.

More from francodacosta.com

© francodacosta.com - All rights reserved