Topic: buildgallary script crashes

I noticed that with my kodak jpg's the script crashes with a fatal error. I found the solution -after digging into the script- in the PHP online manuel. It seems that some image functions needs more memory than normally available for PHP. The solution is to first estimate the memory needed and re-allocate this memory. By the way, it couldn't be solved with the useCopyResized switch.

Additional I needed to reduce the size of the original images as the client browsers became extremely slow when more then 50 photo's are shown. So I've reworked the function createThumb in the buildgallery script to support a 'master' directory which should keep the originals and then the script will generate the compressed photo's for the 'images' directory and the thumbnails in the 'thumbs' directory. The compressed photo's will have the maximum resolution as defined for the client flash viewer (in my case 480x480). So orignal 5M pixel photo's will be reduced to the size of the flash viewer which saves a lot of download time for the clients. In my case the jpg's of 1Mb resized to less than 100Kb.

I hope this will contribute to the use of simpleviewer.

The complete buildgallery.php script becomes:

<?  


set_time_limit&#40;0&#41;;
ini_set&#40;"display_errors" , "1"&#41;;


// -----------------------
// buildgallery.php 
// -----------------------
// by&#58;
// Mario - mariohm@fibertel.com.ar
// Mike Peck - www.mikecpeck.com 
// Mike Johnson - mike@solanosystems.com
// Christian Machmeier - www.redsplash.de 
// Airtight - www.airtightinteractive.com
//
// DESCRIPTION
// -----------------------
// This script automatically generates the XML document and thumbnails for SimpleViewer 
// www.airtightinteractive.com/simpleviewer/
//
// TO USE
// -----------------------
// Instructions are at&#58; www.airtightinteractive.com/simpleviewer/auto_instructions.html
//
// SET GALLERY OPTIONS HERE
// -----------------------
// Set Gallery options by editing this text&#58;

$options = '<SIMPLEVIEWER_DATA maxImageDimension="480" textColor="0xFFFFFF" frameColor="0xFFFFFF" bgColor="0x181818" frameWidth="20" stagePadding="40" thumbnailColumns="3" thumbnailRows="6" navPosition="right" navDirection="LTR" title="Siefkes foto's" imagePath="" thumbPath="">';


// Set showDownloadLinks to true if you want to show a 'Download Image' link as the caption to each image.
$showDownloadLinks = true;

// set useCopyResized to true if thumbnails are not being created. 
// This can be due to the imagecopyresampled function being disabled on some servers
$useCopyResized = false;

// Set sortImagesByDate to true to sort by date. Otherwise files are sorted by filename.
$sortImagesByDate = true;

// Set sortInReverseOrder to true to sort images in reverse order.
$sortInReverseOrder = true;

// END OF OPTIONS
// -----------------------

print "Creating XML and thumbnails for SimpleViewer.<br>"; 
print "-------------------------------------------------<br><br>"; 
//Get GD imaging library info
$tgdInfo    = getGDversion&#40;&#41;; 
if &#40;$tgdInfo == 0&#41;&#123; 
    print "Note&#58; The GD imaging library was not found on this Server. Thumbnails will not be created. Please contact your web server administrator.<br><br>";
&#125;

if &#40;$tgdInfo < 2&#41;&#123;
    print "Note&#58; The GD imaging library is version ".$tgdInfo." on this server. Thumbnails will be reduced quality. Please contact your web server administrator to upgrade GD version to 2.0.1 or later.<br><br>";
&#125;


if &#40;$sortImagesByDate&#41;&#123;
    print "Sorting images by date.<br>";
&#125;else&#123;
    print "Sorting images by filename.<br>";        
&#125;

if &#40;$sortInReverseOrder&#41;&#123;
    print "Sorting images in reverse order.<br><br>";
&#125;else&#123;
    print "Sorting images in forward order.<br><br>";        
&#125;

//loop thru images 
$xml = '<?xml version="1.0" encoding="UTF-8" ?>'.$options;
$folder = opendir&#40;"master"&#41;;
while&#40;$file = readdir&#40;$folder&#41;&#41; &#123;
    if &#40;$file != "." && $file != ".." and $file != "Thumbs.db" &#41; &#123; 
        if &#40;$sortImagesByDate&#41;&#123;
            $files&#91;$file&#93; = filemtime&#40;"master/$file"&#41;;
        &#125;else&#123;
            $files&#91;$file&#93; = $file;
        &#125;
    &#125;        
&#125;    

// now sort by date modified
if &#40;$sortInReverseOrder&#41;&#123;
    arsort&#40;$files&#41;;
&#125;else&#123;
    asort&#40;$files&#41;;
&#125;
foreach&#40;$files as $key => $value&#41; &#123;

    $xml .= '
    <IMAGE>';
    $xml .= '<NAME>'.$key.'</NAME>';
    //add auto captions&#58; 'Image X'
    if &#40;$showDownloadLinks&#41;&#123;        
        $xml .= '<CAPTION><!&#91;CDATA&#91;<A href="master/'.$key.'" target="_blank"><U>Open image in new window</U></A>&#93;&#93;></CAPTION>';
    &#125;else&#123;
        $xml .= '<CAPTION></CAPTION>';
    &#125;
    $xml .= '</IMAGE>';
    
    print "- Created Image Entry for&#58; $key<br>";  

    if &#40;!file_exists&#40;"./images/".$key&#41;&#41;&#123;                    
        if &#40;createThumb&#40;'master/'.$key,'images/'.$key,480,480,true&#41;&#41;&#123;
            print "- Created Image for&#58; $key<br>";              
        &#125;                                    
    &#125;
    if &#40;!file_exists&#40;"./thumbs/".$key&#41;&#41;&#123;                    
        if &#40;createThumb&#40;'master/'.$key,'thumbs/'.$key&#41;&#41;&#123;
            print "- Created Thumbnail for&#58; $key<br>";              
        &#125;                                    
    &#125;
&#125;

closedir&#40;$folder&#41;;

$xml .= '</SIMPLEVIEWER_DATA>';
//next line can cause erroneous warnings
//chmod&#40; 'imageData.xml', 0777 &#41;;
$file = "imageData.xml";   
if &#40;!$file_handle = fopen&#40;$file,"w"&#41;&#41; &#123; 
    print "<br>Cannot open XML document&#58; $file<br>"; 
&#125;  elseif &#40;!fwrite&#40;$file_handle, $xml&#41;&#41; &#123; 
    print "<br>Cannot write to XML document&#58; $file<br>";   
&#125;else&#123;
    print "<br>Successfully created XML document&#58; $file<br>";   
&#125;
fclose&#40;$file_handle&#41;;  

                                                                        
// &#125;&#125;&#125;
// &#123;&#123;&#123; createThumb&#40;&#41;

/**
* Create a squared thumbnail from an existing image.
* 
* @param    string        $file        Location and name where the file is stored .
* @return    boolean
* @access    public
* @author    Christian Machmeier
*/
function createThumb&#40;$file, $fileDest, $outputX = 45, $outputY = 45, $keepratio = false, $quality = 85&#41;
&#123;
    $useCopyResized = false;
    
    // Get information about the installed GD.
    $gdVersion = getGDversion&#40;&#41;;
    if &#40;$gdVersion == false&#41; &#123;
        return false;
    &#125;
    
    // Get the image dimensions.
    $dimensions = @getimagesize&#40;$file&#41;;

    $width        = $dimensions&#91;0&#93;;
    $height        = $dimensions&#91;1&#93;;    
    
    // The image is of horizontal shape, at least more than the output format
    if &#40; &#40;$outputX / $outputY&#41; < &#40;$width / $height&#41; &#41; &#123;
    if&#40; $keepratio &#41;
    &#123;
          $deltaX   = 0;
          $deltaY = 0;
          $portionX = $width;
          $portionY = $height;
          $outputX = $outputX;
      $outputY = &#40;$outputX / $outputY&#41; / &#40;$width / $height&#41; * $outputY;
      &#125; else     &#123;
          $deltaX   = &#40;$width - &#40;$outputX / $outputY&#41; / &#40;$width / $height&#41; * $width&#41; / 2;
          $deltaY =  0;
          $portionX =  &#40;$outputX / $outputY&#41; / &#40;$width / $height&#41; * $width;
          $portionY = $height;
          $outputX = $outputX;
      $outputY = $outputY;
      &#125;

    // The image is of vertical shape.
    &#125; else     if &#40; &#40;$outputX / $outputY&#41; >= &#40;$width / $height&#41; &#41; &#123;
    if&#40; $keepratio &#41;
    &#123;
          $deltaX   = 0;
          $deltaY = 0;
          $portionX = $width;
          $portionY = $height;
          $outputX = &#40;$width / $height&#41; / &#40;$outputX / $outputY&#41; * $outputX;
      $outputY = $outputY;
      &#125; else     &#123;
          $deltaX   = 0;
          $deltaY =  &#40;$height - &#40;$width / $height&#41; / &#40;$outputX / $outputY&#41; * $height&#41; / 2;
          $portionX =  $width;
          $portionY = &#40;$width / $height&#41; / &#40;$outputX / $outputY&#41; * $height;
          $outputX = $outputX;
      $outputY = $outputY;
      &#125;
    &#125;
    setMemoryForImage&#40; $file &#41;;
    
    $imageSrc  = imagecreatefromjpeg&#40;$file&#41;;

    // The thumbnail creation with GD1.x functions does the job.
    if &#40;$gdVersion < 2 || $useCopyResized&#41; &#123;

        // Create an empty thumbnail image.
        $imageDest = imagecreate&#40;$outputX, $outputY&#41;;
        
        // Try to create the thumbnail from the source image.
        if &#40;imagecopyresized&#40;$imageDest, $imageSrc, 0, 0, $deltaX, $deltaY, $outputX, $outputY, $portionX, $portionY&#41;&#41; &#123;
            
            // save the thumbnail image into a file.
            imagejpeg&#40;$imageDest, $fileDest, $quality&#41;;
            
            // Delete both image resources.
            imagedestroy&#40;$imageSrc&#41;;
            imagedestroy&#40;$imageDest&#41;;
            
            return true;
            
        &#125;
        
    &#125; else &#123;    
        // The recommended approach is the usage of the GD2.x functions.
        
        // Create an empty thumbnail image.
        $imageDest = @imagecreatetruecolor&#40;$outputX, $outputY&#41;;
        
        // Try to create the thumbnail from the source image.
        if &#40;imagecopyresampled&#40;$imageDest, $imageSrc, 0, 0, $deltaX, $deltaY, $outputX, $outputY, $portionX, $portionY&#41;&#41; &#123;
            
            // save the thumbnail image into a file.
            imagejpeg&#40;$imageDest, $fileDest, $quality&#41;;
            
            // Delete both image resources.
            imagedestroy&#40;$imageSrc&#41;;
            imagedestroy&#40;$imageDest&#41;;
            
            return true;            
        &#125;        
    &#125;
    
    return false;
&#125;
        
function getGDversion&#40;&#41; &#123;
   static $gd_version_number = null;
   if &#40;$gd_version_number === null&#41; &#123;
       // Use output buffering to get results from phpinfo&#40;&#41;
       // without disturbing the page we're in.  Output
       // buffering is "stackable" so we don't even have to
       // worry about previous or encompassing buffering.
       ob_start&#40;&#41;;
       phpinfo&#40;8&#41;;
       $module_info = ob_get_contents&#40;&#41;;
       ob_end_clean&#40;&#41;;
       if &#40;preg_match&#40;"/bgds+versionb&#91;^dnr&#93;+?&#40;&#91;d.&#93;+&#41;/i",
               $module_info,$matches&#41;&#41; &#123;
           $gd_version_number = $matches&#91;1&#93;;
       &#125; else &#123;
           $gd_version_number = 0;
       &#125;
   &#125;
   return $gd_version_number;
&#125; 

function setMemoryForImage&#40; $filename &#41;&#123;
   $imageInfo = getimagesize&#40;$filename&#41;;
   $MB = 1048576;  // number of bytes in 1M
   $K64 = 65536;    // number of bytes in 64K
   $TWEAKFACTOR = 2;  // Or whatever works for you
   $memoryNeeded = round&#40; &#40; $imageInfo&#91;0&#93; * $imageInfo&#91;1&#93;
                                           * $imageInfo&#91;'bits'&#93;
                                           * $imageInfo&#91;'channels'&#93; / 8
                             + $K64
                           &#41; * $TWEAKFACTOR
                         &#41;;
   //ini_get&#40;'memory_limit'&#41; only works if compiled with "--enable-memory-limit" also
   //Default memory limit is 8MB so well stick with that. 
   //To find out what yours is, view your php.ini file.
   $memoryLimitMB = 8;
   $memoryLimit = 8 * $MB;
   if &#40;function_exists&#40;'memory_get_usage'&#41; && memory_get_usage&#40;&#41; + $memoryNeeded > $memoryLimit&#41; 
   &#123;
       $newLimit = $memoryLimitMB + ceil&#40; &#40; memory_get_usage&#40;&#41;
                                           + $memoryNeeded
                                           - $memoryLimit
                                           &#41; / $MB
                                       &#41;;
      echo "Mem limit set to&#58; " . $newLimit . " MB<br/>rn";
       ini_set&#40; 'memory_limit', $newLimit . 'M' &#41;;
       return true;
   &#125; else
       return false;
   
&#125;

?>

Re: buildgallary script crashes

couldnt you just run the images through a photshop batch resize them locally instead of using the server?

just seems confusing to me as to why you thought a script like this would resize a 1+mb sized image.

also just seems simpler to resize them locally , this way you dont waste time uploading the large images to begin with.

resizing a 5mb 300dpi resolution image to 100-200k 72dpi resolution image using photoshop should clear up any problems of memory exhaustion on the server.