ATTENTION ATTENTION
gear.huuah.com has launched. Visit the shop at http://gear.huuah.com/. Lots of Photo Gear at the moment
ATTENTION ATTENTION
Itsplanned.com is just launched! - Task and project management made easy. Try it for free.

Create your own lists of things to do - arrange the order to do them - move them around - group them

No limitations - all free project management - try the free demo before signing up - demo: itsplanned.com
Faster image scaling within TYPO3 extension
21.08.2009

During the development of a gallery extension for TYPO3, I was having some performance issues when during the on-the-fly image scaling.

When displaying the images in the frontend, I would scale the images to a size specified in the plugin configuration. I was using the following code:

...
$imageConf['file'] = $row[image];
$imageConf['file.']['maxH'] = $this->conf[largeMaxH];
$imageConf['file.']['maxW'] = $this->conf[largeMaxW];
$thumbnailImage = $this->cObj->IMG_RESOURCE($imageConf);
...

The $row[image] would contain the image file to be displayed and the maxH and maxW is being set to the image sizes from the plugin configuration. When loading the page every image would be resized to the correct size, but when a single gallery reached about 100+ images this process started to perform very poorly. Actually is was slow – very slow.

What to do?!

Well, I figured out that I would try to make a function, where the image only would get resized once and then reused. I created an extra database field (a blob-field would be preferred) for storing the cached information.

Generating the images is still done with the above example, but now the filename for the resized image is being saved in the database. I choose a setup using a multidimensional array with keys representing the image height and width like this:

...
$imageConf['file'] = $row[image];
$imageConf['file.']['maxH'] = $this->conf[largeMaxH];
$imageConf['file.']['maxW'] = $this->conf[largeMaxW];
$thumbnailImage = $this->cObj->IMG_RESOURCE($imageConf);

$cached[$this->conf[thumbnailMaxW]][$this->conf[thumbnailMaxH]] = $thumbnailImage;
...

Until now there is no change in the performance as every image still is being resized on the fly. The last piece of the puzzle is to check whether or not there exists a cached image. To do this I am using two check:

$thumbnailImage = $cached[$this->conf[largeMaxW]][$this->conf[largeMaxH]];
if ($thumbnailImage == "" || ! file_exists($thumbnailImage)) {
  $imageConf['file'] = $row[image];
  $imageConf['file.']['maxH'] = $this->conf[largeMaxH];
  $imageConf['file.']['maxW'] = $this->conf[largeMaxW];
  $thumbnailImage = $this->cObj->IMG_RESOURCE($imageConf);

  $cached[$this->conf[thumbnailMaxW]][$this->conf[thumbnailMaxH]] = $thumbnailImage;

  $updateCache = 1;
}

First check is to see if the database contains information about a cached image and the second check is to see if the cache image still exists within the typo3temp directory. If one or both of these check fails, then a new cached image will be generated and the $updateCache is set to 1 indicating that the database should be updated later on in the script.

It’s a while since I made the actual code and I cannot remember the exact render times, but there was a massive performance boost in my extension.

6 Responses to “Faster image scaling within TYPO3 extension”

  1. Yannick Says:

    Hello,

    What about another dimension like so:
    $cached[$this->conf[thumbnailMaxW]][$this->conf[thumbnailMaxH]][] = $thumbnailImage;

    instead ? This would prevent images that have the same dimensions from overwriting your array.

    Cheers

  2. js - huuah Says:

    Hello Yannick

    I think it depends on how you are using the cache function. The way I use the code is by repeating it for every single image and then save the $cached variable as a serialized object in my database. That way it doesn’t comflict with the next image being resized.

    JS

  3. Stephan Petzl Says:

    as far as i know, you dont need this kind of caching stuff, since typo3 has built in caching for images. method $this->cObj->IMG_RESOURCE($imageConf) will check whether there is already a cached image in the temp folder.

    and doing something like this, is a real no-go for extensions:
    $imageConf['file'] = $row[image];
    $imageConf['file.']['maxH'] = $this->conf[largeMaxH];
    $imageConf['file.']['maxW'] = $this->conf[largeMaxW];

    create your configuration in typoscript instead and use it directly!
    like:

    $this->cObj->start($row);
    $content = $this->cObj->cObjGetSingle($this->conf['myconfig'],$this->conf['myconfig.']);

    thats far more reusable!

  4. js - huuah Says:

    Att. Stephan Petzl

    When I did the performance testing, I was getting very long respons times when only using the IMG_RESOURCE method. I will try and see if I can set aside some time, to make a more in-depth test and I will ofcourse post the result here.

    Perhaps you could tell me a bit more, why you think accessing the configuration variable directly is a no-go? Thank you.

  5. Stephan Petzl Says:

    Finally found time to write some lines about this topic. Maybe you figured it out for yourself, but anyway :)
    http://www.ajado.com/blog/how-to-make-a-typo3-extension-configurable/

    BR Steph

  6. js - huuah Says:

    Stephan: Thank you very much for sharing your article – I really appreciate the feedback.

Leave a Reply