Thumbnail code not working. Resize code do, but it's so slow

IMagick is a native PHP extension to create and modify images using the ImageMagick API. ImageMagick Studio LLC did not write nor does it maintain the IMagick extension, however, IMagick users are welcome to discuss the extension here.
Post Reply
iou2
Posts: 4
Joined: 2012-07-14T03:23:44-07:00
Authentication code: 15

Thumbnail code not working. Resize code do, but it's so slow

Post by iou2 »

Hi, my name is Sara and I am using Imagick for the first time on shared LAMP, php version 5.3

During a file upload I am trying to:
1) Create a thumbnail.
2) Resize the image.

Number 1 is not working
Number 2 is working, but only if number 1 is not used.

This is whats phpinfo says:

imagick module version 3.0.1
imagick classes Imagick, ImagickDraw, ImagickPixel, ImagickPixelIterator
ImageMagick version ImageMagick 6.4.8 2009-12-02 Q16 OpenMP http://www.imagemagick.org
ImageMagick copyright Copyright (C) 1999-2009 ImageMagick Studio LLC
ImageMagick release date 2009-12-02

NB: I can not use exec, because of security demands.

I have tried for ages to get it working, but no succes.
Upon succes I happily will remove my install of TimThumb, which doesn't fullfill my requirements.

So please, I do need help.

I apologize for posting the code, please remove it if need be.

Kindest regards

Sara

Code: Select all

<?php
//BOC Image Process

    if (extension_loaded('imagick')) {
// imagick installed
//#####################################################

//BOC thumbnail process
//

// Check if the thumbnails directory exists, if not create it with access rights set to 0775 
    $tn_dir = $this->destination . '/thumbnails/';
//    
    if (is_dir($tn_dir) || @mkdir($tn_dir,0775)) {return TRUE;}

// Delete old thumbnail if it exists
		$old_thumbnail = $tn_dir . $this->filename;
//The function replace_extension is defined at the bottom
    replace_extension($old_thumbnail, 'png');
		if(file_exists($old_thumbnail)) { 
    unlink($old_thumbnail); 
    clearstatcache();
    }

// Create and save a new thumbnail
// Load the image
		$thumbnail = $tn_dir . $this->filename;

// Create an new Imagick object 
    $image = new Imagick($thumbnail);
// Strip out meta data/check if it's an image
    if( $image->stripImage() == true ) {
// The file is an image, continue process

//  Convert to png
    $image->setImageFormat( "png" );
// Get the original dimensions
      $width = $thumbnail->getImageWidth();
      $height = $thumbnail->getImageHeight();
      $bestfit = false;

// Set the thumbnails dimensions (these are treated as maximums and aspect ratio is maintained)
      $thumbnailWidth = max(0,SMALL_IMAGE_WIDTH);
      $thumbnailHeight = max(0,SMALL_IMAGE_HEIGHT);

// determine what to fit to
      if ($thumbnailWidth*$thumbnailHeight != 0) {
      $bestfit = true;
      } else {
      $fitDim = $thumbnailWidth > $thumbnailHeight;
      }
      
// Create thumbnail
      if ($bestfit == true) { 
      $image->thumbnailImage( intval($thumbnailWidth),intval($thumbnailHeight, TRUE)); 
      } else {
      $image->thumbnailImage( $fitDim ? intval($thumbnailWidth) : 0, $fitDim ? 0 : intval($thumbnailHeight), FALSE);
      }
// Make it sharper
      $image->unsharpMaskImage(0 , 0.5 , 1 , 0.05); 

// Save thumbnail
      $image->writeImage($thumbnail);

//Destroy the Imagick object and frees all resources associated with it.
      $image->destroy(); 
    }
//
//EOC thumbnail process
//#
//The above do not work. And, causes the below resize to fail.
//#####################################################

//BOC product image process

// Get the image
      $image_file = $this->destination . $this->filename;
// create new Imagick object
      $image = new Imagick($image_file);
      if( $image->stripImage() == true ) {
// It's an image, continue process

// Set memory limit to 8 MB 
      $image->setResourceLimit( Imagick::RESOURCETYPE_MEMORY, 8 );

//Get the original image type
      $imagePathParts = pathinfo($image_file);
      $image_type = $imagePathParts['extension'];

// Convert to png format (used for simplified processing and better quality)
          $image->setImageFormat( "png" );  

// Set Max vert or horiz resolution
          $maxsize = 480;// 320 is exactly 20em and 480 is exactly 30em (half the 960 grid)
// Resizes to whichever is larger, width or height
        if($image->getImageHeight() <= $image->getImageWidth())
          {
// Resize image using the lanczos resampling algorithm based on width
        $image->resizeImage($maxsize,0,Imagick::FILTER_LANCZOS,0.75);
// Resize image using the catrom resampling algorithm based on width, faster than lanczos
//          $image->resizeImage($maxsize,0,Imagick::FILTER_CATROM,0.75); <--------------------did not work, even without thumbnail code
          } else {
// Resize image using the lanczos resampling algorithm based on height
        $image->resizeImage(0,$maxsize,Imagick::FILTER_LANCZOS,0.75);
// Resize image using the catrom resampling algorithm based on height, faster than lanczos
//          $image->resizeImage(0,$maxsize,Imagick::FILTER_CATROM,0.75); <--------------------did not work, even without thumbnail code
          }

// Make it sharper
          $image->unsharpMaskImage(0 , 0.5 , 1 , 0.05); //For center part
          $image->sharpenimage( 0.8, 0.6);
          $image->contrastImage( 5 );

// Set compression type for png's
        $image->setInterlaceScheme(Imagick::INTERLACE_PNG);
        $image->setCompression(Imagick::COMPRESSION_ZIP);
        $image->setImageCompressionQuality(90);      

// Convert back to original type
          $image->setImageFormat( $image_type );

// Write resultant image to the original uploaded file
          $image->writeImage($image_file);

//Destroy the Imagick object and free all resources associated with it.
          $image->destroy();
//    
//EOC product image process
//
  }
}
//EOC Image Process
//#
    function replace_extension($filename, $new_extension) {
      $info = pathinfo($filename);
      return $info['filename'] . '.' . $new_extension;
    }
?>
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Thumbnail code not working. Resize code do, but it's so

Post by Bonzo »

If I was you I would start with something simple and take out everything apart from the thumbnail section and get it working then add it to your code - to prove the thumbnail is working. I have started to create some Imagick examples on my website and it is a shame you can not use exec() as it is easier and has more options.

Anyway the options for thumbnail changed on one of the versions of Imagick but I am not sure when. I belive at one point I needed to use 0 or 1 rather than True or False.

Your thumbnailing code looks OK.

If thumbnailing you should not need to strip as it is the reason to use thumbnail instead of resize.
iou2
Posts: 4
Joined: 2012-07-14T03:23:44-07:00
Authentication code: 15

Re: Thumbnail code not working. Resize code do, but it's so

Post by iou2 »

Hi Bonzo, nice nick! :)

I have changed the logic to first create the resized image, which works but isn't blending fast...
So I tried: $image->setResourceLimit( Imagick::MAGICK_THREAD_LIMIT, 1 );
which resulted in: Undefined class constant 'MAGICK_THREAD_LIMIT' and a blank screen.

The thumbnailing, however, still doesn't work.

Don't what to do, I will try to use the resize code to see what's happening.

Could it be a installation issue?

Sara
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Thumbnail code not working. Resize code do, but it's so

Post by Bonzo »

My dad calls me Bonzo !

I have just tried your thumbnail code - are you not getting any errors?

I had a few; for a start:

Code: Select all

// Get the original dimensions
      $width = $thumbnail->getImageWidth();
      $height = $thumbnail->getImageHeight();
      $bestfit = false;
$thumbnail is not correct as it should be $image as you created a new imagick object from $thumbnail called $image

I then had problems with this line:

Code: Select all

$image->thumbnailImage( $fitDim ? intval($thumbnailWidth) : 0, $fitDim ? 0 : intval($thumbnailHeight), FALSE);
Using this code " echo $fitDim ." - ".$thumbnailWidth." - ".$thumbnailHeight;" my output was: - 0 - 0
Which can not be correct as there is no value for $fitDim and the othe two were 0, I did not try your full code as I do not know how it is called etc. which may be part of my problem.

As I suggested I would try bits of your code out one at a time to find the problem and/or echo your variables at each step to see they contain what you expect.
Last edited by Bonzo on 2012-07-14T14:15:07-07:00, edited 2 times in total.
User avatar
fmw42
Posts: 25562
Joined: 2007-07-02T17:14:51-07:00
Authentication code: 1152
Location: Sunnyvale, California, USA

Re: Thumbnail code not working. Resize code do, but it's so

Post by fmw42 »

There is a more current version of Imagick http://pecl.php.net/package/imagick/3.1.0RC2
iou2
Posts: 4
Joined: 2012-07-14T03:23:44-07:00
Authentication code: 15

Re: Thumbnail code not working. Resize code do, but it's so

Post by iou2 »

Hi!

Low and behold I've got it working! :)

Although still one flaw, I am trying to save the thumbnail in png format:

Code: Select all

// oldpath
//      $thumbnail = $this->destination . $this->filename;
// newpath
 		$thumbnail = $tn_dir . $this->filename;
// Tried:
// $thumbnail->setImageFormat( "png" );// PHP Fatal error:  Call to a member function setImageFormat() on a non-object
// During the above process, the image was converted to format 'png'. How do I save the image in this format?
// Save thumbnail
      $image->writeImage($thumbnail);

//Destroy the Imagick object and frees all resources associated with it.
      $image->destroy(); 
//
//EOC thumbnail process
So, how do I do it?

I must say that Imagick is a wonderful extension...

Sara
Bonzo
Posts: 2971
Joined: 2006-05-20T08:08:19-07:00
Location: Cambridge, England

Re: Thumbnail code not working. Resize code do, but it's so

Post by Bonzo »

Glad its now working - just out of interest Imagick is not written/supported by the Im developers.

You need to change the extension:

Code: Select all

// Piece of code found on the web - probaly not quite how I would do it
$new_name = substr_replace($thumbnail , 'png', strrpos($thumbnail , '.') +1) 
$image->writeImage($new_name);
iou2
Posts: 4
Joined: 2012-07-14T03:23:44-07:00
Authentication code: 15

Re: Thumbnail code not working. Resize code do, but it's so

Post by iou2 »

Hi again, first thanks for the download link. I will study the code, most likely I will find something useful. Thanks! :)

After tweaking and twiddleing my code I am almost done.

You can se the resize result here: http://www.u2commerce.com/product_info. ... ucts_id=81

My test revealed:

Test image
original 632x670, size: 420.093 Kb
Stripped, compressed and resized to max 480px, Size 126,836 Kb
thumbnail_png, size 100px: 35.542 Kb <-----------!!
thumbnail_jpg, size 100px: 8.013 Kb
Recommendations:
Set Max vert or horiz resolution to 360
Set small_image_width to 96, which is exactly 6em
Use format jpg for the thumbnails

If you would like to have the original image to experiment with, please let me know.

I have 4 questions left:

1) How do I use cache with Imagick?

2) What's the difference between these:

-a: $image->clear();
-b: $image->destroy();

3) Is there a "smart" image helper, with a unix timestamp for the image so the search engines updates to the latest image?
(Avoiding 404 errors)

4) Are there anyone who would love to optimize my code, among other things to get it faster?

Kind regards and many thanks for a fantastic piece of art called Imagick!

Sara
Post Reply