ZoomifyImage ported to PHP

Wes Wright has ported Adam Smith‘s ZoomifyImage processor from Python to PHP. This is a tool that lets you convert images to a format that can be viewed using the flash based Zoomify viewer.

Wes gave me the go-ahead to write a bit about his work on this and put it up for download. Additionally, I’ve modified the scripts I had originally written that used the python tools so they work with Wes’s ZoomifyFileProcessor class.

Batch converting images to the zoomify format

Besides consolidating a few files, the code and functionality of my old “wrapper” scripts
hasn’t changed from when they employed the python tools to do the heavy lifting. The big difference is that we no longer have to rely on system calls and command line execution. So, provided you are running a relatively up to date version of PHP (compiled with GD), no more libraries to install, or packages to upgrade.

What this means for us is that we can finally do web based image processing. Using Wes’s port and a few additional utility functions, we can set up an interface that will let us convert a directory of images into a format that can be loaded into the flash based Zoomify image viewer.

Safe mode, and GD image size limits

If you are running under safe mode, note that you’ll have to be authenticated (i.e. with HTTP Auth) as the owner of the directory that ZoomifyFileProcessor is writing to. If you are using groups, you may also need to jump through some more hoops.

I think I’ve run into a few issues on some systems processing images using the GD Library. It appears that GD sometimes has problems with images over a certain dimensional size (as opposed to file size). I haven’t been able to confirm this, or test it extensively, so it’s just a hunch. Your mileage may vary.


The relevant files are listed below:


  1. Gravatar Icon
    Posted June 7, 2007 at 2:15 am | #

    I’ve also written a PHP function that will zoomify an image…I have not tested its limits as far as image dimensional size, nothing I’ve thrown at it has caused it to puke.

    I’m curious about when Zoomify uses more than one image as the base of its tiling. Using their free converter, I never had it produce more than one tile group. I noodled out how zoomify works rather than consulting any specs, perhaps it would behoove me to do so.

  2. Gravatar Icon
    Posted June 11, 2007 at 10:24 pm | #

    We’ve used some pretty large images in the past, and it’s given us multiple tile groups. I’m not clear on what causes it to use more than one group, but I haven’t looked that closely.

    FWIW, I think Adam’s Python version of the converter was built with some form of input from the folks at Zoomify. I gather that Wes pretty much did a line-by-line port of Adam’s Python version.

    I’d be curious to see what you’ve put together, so if you end up publishing yours, give us a ping!

  3. Gravatar Icon
    Posted June 18, 2007 at 2:51 am | #

    Hey Justin,
    Great scripts. I’ve gotten them set up on a mac running MAMP 1.6.1. When using the example.php it stalls out at the “openimage” step. Any Ideas what might be going on?

    Here is what my php_error logs say:

    ===== Monday, June 18, 2007 12:49:28 AM US/Pacific =====
    [18-Jun-2007 00:49:34] PHP Notice: Undefined index: action in /Applications/MAMP/htdocs/zoomify-image-php/example.php on line 19
    [18-Jun-2007 00:49:35] PHP Notice: Undefined property: ZoomifyFileProcessor::$file in /Applications/MAMP/htdocs/zoomify-image-php/ZoomifyFileProcessor.php on line 421
    [18-Jun-2007 00:49:35] PHP Fatal error: Allowed memory size of 8388608 bytes exhausted (tried to allocate 15488 bytes) in /Applications/MAMP/htdocs/zoomify-image-php/ZoomifyFileProcessor.php on line 99

    and this is the example.php result:

    Processing all files in /Applications/MAMP/htdocs/zoomify-image-php/images/ …

    Skipping /Applications/MAMP/htdocs/zoomify-image-php/images/.DS_Store… (/Applications/MAMP/htdocs/zoomify-image-php/images/ exists)
    Processing /Applications/MAMP/htdocs/zoomify-image-php/images/test.jpg…
    getImageMetadata for file /Applications/MAMP/htdocs/zoomify-image-php/images/test.jpg originalWidth=3872 originalHeight=2592 tilesize=256
    getImageMetadata newWidth=1936 newHeight=1296
    getImageMetadata newWidth=968 newHeight=648
    getImageMetadata newWidth=484 newHeight=324
    getImageMetadata newWidth=242 newHeight=162
    processImage root=/Applications/MAMP/htdocs/zoomify-image-php/images/test ext=.jpg
    openImage /Applications/MAMP/htdocs/zoomify-image-php/images/test.jpg

  4. Gravatar Icon
    Posted June 18, 2007 at 9:04 am | #

    @Dane – It sounds like you may be running up against the default memory usage limit for yor PHP install (that’s why you’re getting the “PHP Fatal error: Allowed memory size of 8388608″ error in your logs).

    You might be able to use PHP’s ini_set() function at the top of your scripts to increase the memory_limit directive.

  5. Gravatar Icon
    Posted June 18, 2007 at 12:09 pm | #

    Thanks! I’m not familiar with writing php so I went into the php.ini doc itself with a text editor and bumped up the memory allocation. This did solve that fatal error seen in the logs but did not help the example.php script move past the “openimage” step.

    But then i changed from running php5 to php4 and immediately everything works perfectly!

  6. Gravatar Icon
    Posted June 18, 2007 at 12:16 pm | #

    @Dane – Glad you got it working. You bring up a good point, which I’ve falied to mention, in that this had only been tested on PHP 4.x. Sounds like there may be some issues running it under PHP 5. Thanks for following up with that info!

  7. Gravatar Icon
    Posted July 11, 2007 at 5:28 pm | #

    Justin and Wes, congratulations on evolving this PHP approach to using Zoomify, I’m sure it will be in great demand. (I may use it myself…) Have you guys thought of writing plugins to integrate this with some of the many open source photo galleries and CMS’s written in PHP? There have been requests for Zoomify integration with Gallery2 in the past, and I have thought of tackling this, but haven’t found the time–and I may never find the time.

    I am going to update the ZoomifyImage readme file in CVS to link to this blog post, and I was also thinking of posting a message on the SourceForge support forum for ZoomifyImage to help people find this code through there, unless you want to do that yourselves. Also, let me know if you want to update the contrib folder with the code for this new approach and any documentation.

    To answer the question about tile group folders:

    Tiles are saved in directories or folders in groups of 256. These directories also follow a naming convention, beginning with the ‘TileGroup0′ directory, then ‘TileGroup1′ and so on. The Zoomify viewer expects lower numbered tile groups to contain tiles for lower numbered tiers. So, the 0-0-0.jpg image will always be in TileGroup0.

    The readme file in ZoomifyImage goes into all the gory details of the entire process if anyone is interested.

  8. Gravatar Icon
    Posted July 11, 2007 at 8:56 pm | #

    @Adam – I hadn’t given any thought to building it into those type of packages myself, but I like the idea. On the other hand, I’d almost rather focus on streamlining it and applying bugfixes, such as making sure it works w/ php5. Integrating it into other people’s projects does sound like more fun, though. :)

    As for posting to the sf forum, I’d say go for it – chances are I wouldn’t get to it any time soon (I intended to make a post on your blog about this, but never got around to it).

    I don’t have much documentation for this tool, and the “wrapper” class for this isn’t a whole lot different from the original, so the stuff in the contrib dir might be ok as is. You’re free to add it if you’d like, of course.

    Thanks for stopping by!

  9. Gravatar Icon
    Posted July 13, 2007 at 3:06 pm | #

    I have implemented this but find it distorts the bottom row if its not the correct 256 size.

    Can anyone confirm this?

  10. Gravatar Icon
    Posted August 10, 2007 at 8:15 am | #


    I’ve also found that when implementing the script (which otherwise works great!) for very big images, it crashes because of the php memory limit (tried with 32M and 64M), so I’ve looked a little into the code and found that you can overcome this just by doing some memory clean-up before the processRowImage function recursively calls itself.

    Namely, it helps if you call an imagedestroy before the if ($tier > 0) on line 312 (in the processRowImage function). Just add: imagedestroy($imageRow); before these lines: if ($tier > 0) { if ($this->_debug) print “processRowImage final checks for tier $tier row=$row rowsForTier=$rowsForTier\n”.

    Hope it’s of some help. Thanks.

  11. Gravatar Icon
    Posted August 13, 2007 at 4:50 pm | #

    The Brain Maps API is a lightweight multiresolution image viewer that lets you view Zoomify images. It has been designed to be small and fast, and to consume very little memory, yet still be very functional and extensible. Future versions will enable you to add overlays to multiresolution images (including markers and polylines) and to display clickable labels. The Brain Maps API is a free service, available for any web site that is free to consumers. Available at http://brainmaps.org/index.php?p=brain-maps-api

  12. Gravatar Icon
    Posted August 14, 2007 at 9:53 pm | #

    @marian – thanks so much for the tip – maybe this will solve some of the issues I was running into on a few systems. I’ll try and update the code soon to reflect your changes. I’ll also try to either take Adam up on his offer of getting this into sourceforge, or put this thing in Google code (at this point I have a preference for Subversion over CVS) …

    @John – Brain Maps looks pretty cool. Nice to have an alternative to loading these things in Flash.

  13. Gravatar Icon
    Ciaran Clissmann
    Posted September 19, 2007 at 1:29 pm | #

    I’ve happily zoomified a jpeg image with the zoomify code (python version), as an extension to earlier work. It’s at http://staging.askaboutireland.ie:8080/gv2/z/zoomifyDynamicViewer.php?file=LIMERICK/05&path=./pix/&livery=sz

    But I’d like to be able to zoom in a bit closer. Presumably that means creating more tiles at zoomify time. How do you tell the system what level of detail you want, or how close you want to be able to zoom in to ?



  14. Gravatar Icon
    Posted September 19, 2007 at 2:37 pm | #

    @Ciaran – I’ve been operating under the assumption that the bigger the original image, the deeper the “zoom”. For images that we wanted to be able to zoom in farther on, we’ve asked for higher resolution files where possible. Someone with closer knowledge of the nuts and bolts of how the converter works might be able to shed more light on this.

  15. Gravatar Icon
    Ciaran Clissmann
    Posted September 20, 2007 at 4:03 am | #


    you’re absolutely right. I uploaded a much bigger file, and the end result is much much better.

    Again, thanks for the help!


  16. Gravatar Icon
    Posted April 9, 2008 at 2:53 pm | #

    Hi Justin
    I’ve been trying to use exec() to use the (original) Zoomify .exe converter. It has been a very unstable process. So I was searching for alternatives and stumbled over your php version.

    I’m quite new to PHP, would you mind giving the most simple version of using the class ?

    So I was thinking something like :
    $zoomify = new ZoomifyFileProcessor();
    $zoomify->zoomifyProcess($pathtoimage, $pathtodestinationdirectory)

    See where I’m heading ? I’d like to be able to use it and define what image to process with it’s complete path + the destination dir for the tiles.

    Is that possible ?

    Hope to hear from you :-D


  17. Gravatar Icon
    Posted June 17, 2008 at 7:38 pm | #

    @Jonathan – I have the same problem. All of the bottom tiles (except those of the non-resized image) are stretched out vertically. Does anyone have a fix for this? Regardless, I’m going to check the source to see if I can find out what’s wrong.

  18. Gravatar Icon
    Posted June 25, 2008 at 11:06 am | #


    I have this error page during converting images. Please help

    Thank you


    Processing all files in /conv/images/ …

    Processing /conv/images/obraz.jpg…

    Warning: chgrp() [function.chgrp]: Unable to find gid for user in /conv/ZoomifyFileProcessor.php on line 448

    Warning: chgrp() [function.chgrp]: Unable to find gid for user in /conv/ZoomifyFileProcessor.php on line 426

    Fatal error: Using $this when not in object context in /conv/ZoomifyFileProcessor.php on line 59

  19. Gravatar Icon
    Posted June 25, 2008 at 1:43 pm | #

    @Marek – I had the same problem. Try commenting those lines out. It worked for me.

    As for the distortion of the bottom rows, I’ve located the problem. It is the processRowImage() function in ZoomifyFileProcessor.php. Specifically, the parameters for resizing and resampling images. Some images are being stretched to fit the correct tile size instead of being resized.
    I’m completely confused about how to fix it…

  20. Gravatar Icon
    Posted August 6, 2008 at 7:39 pm | #

    it’s work greately in php, although i use it for generating tile for 10000 * 20000 pixel image, itz amazing…but did u know, what methode are using in the fileprocecor.php..i heard its use pyramid tile,is this something like gaussian pyramid method or laplacian?

  21. Gravatar Icon
    Posted October 17, 2008 at 4:28 pm | #

    To fix the distortion of the last row….

    Change the dst_h of the resize and resample calls to the src_h. This will prevent stretching of the tile.

  22. Gravatar Icon
    John Bauer
    Posted November 26, 2008 at 3:31 pm | #

    Hello, I found the problem with PHP5. In the utility function imageCrop in ZoomifyFileProcessor.php line 59 references $this->_debug however the function is not a member of a class:

    /* : Line 59 ZoomifyFileProcessor.php */
    if ($this->_debug) print “imageCrop x=$x y=$y left=$left upper=$upper right=$right lower=$lower\n”;

    It’s not a method on the ZoomifyFileProcessor class, I’m guessing PHP5 is more strict with variable scope.


  23. Gravatar Icon
    Posted April 9, 2009 at 11:16 am | #

    Some of our subdirectorys have dots in so I neede to replace some code:


    list($root, $ext) = explode(“.”,$this->_v_imageFilename) ;
    $exploded_items = explode(“.”,$this->_v_imageFilename) ;
    $ext = array_pop($exploded_items);
    $root = implode(“.”, $exploded_items);

  24. Gravatar Icon
    Posted June 12, 2009 at 5:25 am | #

    Thanks, this script is really nice and usefull!

  25. Gravatar Icon
    Posted June 15, 2009 at 10:20 am | #

    I’m still trying to convert (really) big images and got a (kind of) timeout.

    Using PHP CLI on Debian/Celeron 1.20+ GHz/1Go DDR2 and a 220MiB jpeg, i’m waiting ~3 minutes with the message “openImage /var/www/begroup/z/images/heic0707a.jpg” and getting a “Process Endend” (“Processus arrêté” in my natural language).

    I’ve put ob_flush() / flush() after all debug message and ini_set (‘max_execution_time’, 0) / ini_set (‘set_time_limit’, 0) on after “list($ul_y, $lr_y) = array(0,0);” in the function processImage()…

    They’re is anybody who try to convert big (100MiB or more (and when I say more I mean MORE like +1GiB!!)) and succeeded?
    They’re is any workaround to fix this?
    It’s the PHP’s fault ? Linux fault ? Memory’s fault ? Both ?

  26. Gravatar Icon
    Posted June 16, 2009 at 4:56 am | #

    Today I’ve tryed Python script for convert image… I got the same problem: He create the “TileGroupXX” directories, consumes 99% of ram and between 50 & 90% of processor during 3 minutes and *Pouf* -> [1]+ Processus arrêté python ZoomifyFileProcessor.py /var/www/begroup/z/images/z/heic0707a.jpg

    I really need help on this case! Thanks anyway for this good port!

    You cna find this picture here: http://www.spacetelescope.org/images/original/heic0707a.tif (~500MiB in tif, ~200 in jpeg at 100%)

  27. Gravatar Icon
    Logan Waggoner
    Posted June 25, 2009 at 4:26 am | #

    Can verify bug with subdirectories containing a “.” in them

    Also, the above poster forgot to mention the bug occurs in 2 places, the processImage() function and the processRowImage function.


    function getRoot()
    $exploded_items = explode(“.”,$this->_v_imageFilename) ;
    $ext = array_pop($exploded_items);
    $root = implode(“.”, $exploded_items);

    Replace $this->getRoot();

    with all occurances of:

    list($root, $ext) = explode(”.”,$this->_v_imageFilename) ;

    There is a point where another explode occurs in the createDataContainer function, but it works. Also, if you turn on debug the directories are displayed incorrectly. However it works correctly.

  28. Gravatar Icon
    Posted July 30, 2009 at 9:25 am | #

    Can anybody post the exact code changes of Ryan’s solution to fix the distortion of the last row, please? I tried to change several lines, but I don’t exactly understand what lines I need to change.

  29. Gravatar Icon
    Posted December 16, 2010 at 7:05 pm | #

    For anyone who can’t figure out the stretching issue go to line 235 and change the dst_h value to $secondRowHeight. This will fix your stretching issue.

  30. Gravatar Icon
    Shadi Alian
    Posted November 18, 2011 at 10:47 am | #

    I am using the script to generate tiles but i am running into a problem, the original images have transparent background but the generated tiles have black background. is there a way we can keep the transparent background.

  31. Gravatar Icon
    Posted June 21, 2014 at 11:16 am | #

    Hmm it appears like your website ate my first comment (it was super
    long) so I guess I’ll just sum it up what I submitted and say, I’m thoroughly enjoying your blog.

    I too am an aspiring blog writer but I’m still new to everything.
    Do you have any suggestions for rookie blog writers? I’d definitely
    appreciate it.

  32. Gravatar Icon
    Posted June 23, 2014 at 5:54 pm | #

    Great items from you, man. I have be mindful your stuff prior
    to and you are just too wonderful. I really like what you have bought here, certainly like what you’re saying and the best way
    wherein you say it. You make it entertaining and
    you still take care of to keep it sensible. I cant wait to learn far
    more from you. That is actually a tremendous site.

  33. Gravatar Icon
    Posted June 24, 2014 at 2:54 am | #

    It’s genuinely very complex in this busy life to listen news on Television, thus I just use internet for that reason, and get the most up-to-date news.

  34. Gravatar Icon
    Posted June 24, 2014 at 3:09 am | #

    Great post. I used to be checking constantly this weblog and I’m
    inspired! Very useful info specifically the closing part :
    ) I take care of such info much. I was seeking this certain info
    for a very long time. Thanks and best of luck.

  35. Gravatar Icon
    Posted June 25, 2014 at 11:41 am | #

    Right here is the perfect site for anyone who really wants to find out
    about this topic. You understand a whole lot its almost hard to argue with you (not that I personally would want to…HaHa).
    You certainly put a new spin on a subject that has been discussed for a long time.
    Excellent stuff, just excellent!

  36. Gravatar Icon
    Posted June 26, 2014 at 1:04 pm | #

    Pretty nice post. I simply stumbled upon your weblog and wanted to mention that
    I’ve really enjoyed surfing around your weblog posts. After all I’ll be subscribing for your rss feed and I’m hoping you write once more very soon!

  37. Gravatar Icon
    Posted June 29, 2014 at 5:24 pm | #

    They try driving iin traffic from blogs, and then he reduces the price action in Asian and Eastern European countries.Gradually enable each add-on one
    at a time when the economy is so since the moee exposure!
    The makers of of the network, rather than blo business obstructing free enterprise.

  38. Gravatar Icon
    Posted August 16, 2015 at 10:22 am | #

    ID cards have definitely become part of the daily uniform that thousands of employees wear everyday to work.

4 Trackbacks/Pingbacks

  1. [...] noted in a previous article regarding Zoomify, you may have to take special steps if you are running under safe mode. [...]

  2. [...] ZoomifyImage ported to PHP » Justin Henry’s green galoshes (tags: php zoomify image) [...]

  3. [...] above image was tiled using ZoomifyImage (ported to PHP), it is displayed using the combination of Leaflet and Bjørn Sandvik’s [...]

  4. [...] The PHP preprocessing script was derived from work by Wes Wright and published by Justin Henry. [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *

You can follow any discussion on this article with the RSS feed for this post.

About this article

Green Galoshes is a weblog written by Justin D. Henry. This entry was published on or around May 25, 2007.

Categories & Tags

This article is filed under code, projects, reference. It is further described as , , , , , , , , , , .