5

I have a script that makes thumbnails of the pictures in a directory. But it's execution takes too long (about 170 images in the directory).

The script is called by ajax request. After 70% completion, I receive an error probably due to time out (takes about 3-4 minutes).

How can I solve this issue?

function createThumbs( $pathToImages, $pathToThumbs, $thumbWidth ) 
{
 // open the directory
 $dir = opendir( $pathToImages );

 // loop through it, looking for any/all JPG files:
while (false !== ($fname = readdir( $dir ))) {
// parse path for the extension
$info = pathinfo($pathToImages . $fname);
// continue only if this is a JPEG image
if ( strtolower($info['extension']) == 'jpg' ) 
{

  // load image and get image size
  $img = imagecreatefromjpeg( "{$pathToImages}{$fname}" );
  $width = imagesx( $img );
  $height = imagesy( $img );

  // calculate thumbnail size
  $new_width = $thumbWidth;
  $new_height = floor( $height * ( $thumbWidth / $width ) );

  // create a new temporary image
  $tmp_img = imagecreatetruecolor( $new_width, $new_height );

  // copy and resize old image into new image 
  imagecopyresampled( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

  // save thumbnail into a file
   imagejpeg( $tmp_img, "{$pathToThumbs}thumb_{$fname}" );
   }
  }
   // close the directory
  closedir( $dir );
  }

  createThumbs($directory,$directory."/thumbs/",150);

ajax call;

   var ajaxr=$.ajax({
  type: "POST",
  url: "after_upload.php",
  timeout:600,
  beforeSend: function() {
  $("#result").html('<div align="center"><h2>מבצע עיבוד נתונים יקח זמן ,חכה..תכין קפה בנתיים      ותעשן סיגריה</h2><div><img src="loader.gif"/><div dir="rtl" style="margin:15px;">טוען מידע וממיר תמונות... <button id="cancel" style="padding:5px;">בטל פעולה ותחזור חזרה [X]</button></div></div>  </div>');
                        },
  success: function(data){
       $("#result").html(data);
  },
  error: function(xhr, textStatus, errorThrown) {
                             $("#result").html(textStatus);
                        }
  });

now,increased the time out to 3000 in ajax call and it instantly,for some reason return timeout error.if i remove time out property from the call ..it preforms the call and script executes..but only 70% of job is done..done returned empty error...

UPDATE:..i preformed everythin to make script execution time better now:console return 404 Not Found..

  • 5
    Processing 100+ images is heavy duty task. You can set that script to run via PHP CLI + cron instead. – Salman A May 07 '13 at 08:55
  • Please add the error message you get. – prehfeldt May 07 '13 at 08:55
  • you can probably set a long timeout value .ref:`http://api.jquery.com/jQuery.ajax/` – dreamweiver May 07 '13 at 08:58
  • it's probably better to submit the job on the ajax call to process in the background and then have the response check for whether the job finished. In that case you don't have to worry about the time. – user1914292 May 07 '13 at 08:59
  • Why does it matter if an async jQuery ajax request times out? Just don't specify a callback function you would expect to run. – vinczemarton May 07 '13 at 09:01
  • @user1914292: But the ajax doesnt return the success message until the operation is completely done. – dreamweiver May 07 '13 at 09:02
  • 3
    @user2268106 Even if the script does not time out, its not a good idea to process this kind of request on the fly. Waiting for an output of an ajax request till 3-4 minutes is a bad idea. If you could tell us your use case, you can get better ideas. – Ankit Jaiswal May 07 '13 at 09:06
  • the problem,is,just that icant make cron job,its a part of some system that i build for image managment..it needs to be simple to install – user2268106 May 07 '13 at 09:31

3 Answers3

5

Make the creation of the thumbnail run in a loop and after every loop remove the previous resource from the server memory.

imagedestroy($thumb);
imagedestroy($source);

This would greatly help, I just finished something very similar.

George
  • 3,757
  • 9
  • 51
  • 86
0

From a coding point of view, there is little you can do to your script to speed it up, after all, processing 100+ images is not a simple task.

However, you can quite easily set the script timeout to prevent a 'timeout' error from occuring. You can either set this in the php.ini, or alternatively, you can set it in the PHP script itself like so:

// Set the seconds (2 minutes)
$seconds = 120;

// Set the maximum execution time
set_time_limit($seconds);

See here for further information on set_time_limit().


Whilst the above may solve your issue, you would be much better off running this script via Windows Task Scheduler, or Cron (depending on your OS). Using this method, you can execute the script at certain time intervals.

The schedule solution above will only be a suitable solution if the 'image processing' that you are doing is not event based. By this I mean that the images do not need to be processed when your user does something particular such as clicking a button...

Ben Carey
  • 16,540
  • 19
  • 87
  • 169
0

found the issue ..server idle(apache) was set to 2min..script loops throu dir of 170 images and creates thumbs for 3 min..becouse server wont return answer connection was dropped.The solution was James Okpe George's suggestion which reduced obout half second per image,next in my case all images were same size so made the thumbs based only on first image in directory..reduced-half second per image.After that i splitted the whole process in 2 [get thet list of directory]=>array it ..return response..second call to make thumbs.. 1.2 mins for 170...not bad.