Loop only seems to run once

I have a directory of images.
I tried to create thumbnails of each image, but with this, only 1 seems to get produced.

<?php
$providerID = $_GET['providerID'];

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

// loop through it, looking for any/all files:
while (false !== ($fname = readdir( $dir ))) {
// parse path for the extension
$info = pathinfo($pathToImages . $fname);
// continue only if this is a image
 if ( strtolower($info['extension']) == 'jpg' || strtolower($info['extension']) == 'jpeg' || strtolower($info['extension']) == 'png' || strtolower($info['extension']) == 'gif') 
{
  //echo "Creating thumbnail for {$fname} <br />";

  // 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 
  imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

  // save thumbnail into a file
  imagejpeg( $tmp_img, "{$pathToThumbs}{$fname}" );
	echo '<div class="thumbnail with-caption">';
	echo '<img src="'.$pathToThumbs.$fname.'" class="img-rounded">';
	echo '</div>'; 
}
  // close the directory
closedir( $dir );
}
}

createThumbs("../providers/{$providerID}/","../providers/{$providerID}/thumbs/",200);

?>

I thought since I have it in the if loop they would all get made?
How can I make it go through every image?

Try adding this line immediately after the loop starts to see if the files correspond to the actual files in the directory.

``’
echo ‘
’. $pathToImages . $fname;

Double-check your location for closedir…

(proper indenting might help…)

1 Like

Can I recommend that you try using the glob() function? http://php.net/manual/en/function.glob.php

It’s really simple. You can do something like:

foreach (glob($pathToDir."/*.jpg") AS $jpg) {
    // Do something with $jpg
}

You can make the pattern something like /*.{jpg,jpeg,gif,png} to search for all jpg, jpeg, gif and png files at once. glob() returns an array so you can iterate over it easily. If it doesn’t match it will return an empty array, but if there’s an error it will return false.

Small detail, but it removes some of your logic needing to process the extension etc and removes the need to use opendir(), readdir() and closedir()

thanks starlion, that worked as the closedit() was inside the while loop, I put it outside and it seems to work.
For some reason, thumbnails are only generasted for the images ending in .jpg (the .gif doesn’t seem to work)
I thought this bit of code would take care of that…

if ( strtolower($info['extension']) == 'jpg' || strtolower($info['extension']) == 'jpeg' || strtolower($info['extension']) == 'png' || strtolower($info['extension']) == 'gif') 
    {

but I gather it might be more straightforward if I replace that with

foreach (glob($pathToImages."/*.(jpg,jpeg,gif,png,bmp") AS $image) {

To include the 5 possible extensions, then I guess a switch statement is in order…
Found this…

<?php 
function imageCreateFromAny($filepath) { 
$type = exif_imagetype($filepath); //  if you don't have exif you could use getImageSize() 
$allowedTypes = array( 
    1,  // [] gif 
    2,  // [] jpg 
    3,  // [] png 
    6   // [] bmp 
); 
if (!in_array($type, $allowedTypes)) { 
    return false; 
} 
switch ($type) { 
    case 1 : 
        $im = imageCreateFromGif($filepath); 
    break; 
    case 2 : 
        $im = imageCreateFromJpeg($filepath); 
    break; 
    case 3 : 
        $im = imageCreateFromPng($filepath); 
    break; 
    case 6 : 
        $im = imageCreateFromBmp($filepath); 
    break; 
}    
return $im;  
} 
?>

Then can I add that function to createThumbs()…

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

// loop through it, looking for any/all files:
foreach (glob($pathToImages."/*.(jpg,jpeg,gif,png,bmp") AS $image) {

imageCreateFromAny($image);

$width = imagesx( $im );
$height = imagesy( $im );

// 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 
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file  (am unsure of this)
imagejpeg( $tmp_img, "{$pathToThumbs}{$fname}" );

echo '<div class="thumbnail with-caption">';
echo '<img src="'.$pathToThumbs.$fname.'" class="img-rounded">';
echo '</div>'; 
  }
// close the directory
closedir( $dir );
}

I think im on to something here
(but am confused on saving the new image in its original format)
Thank you for your help…

So my recommendation would be to abuse a trick of PHP - variable functions.

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

// loop through it, looking for any/all files:
foreach (glob($pathToImages."/*.(jpg,jpeg,gif,png,bmp") AS $image) {
$type = exif_imagetype($filepath); //  if you don't have exif you could use getImageSize() 
$allowedTypes = array( 
    1,  // [] gif 
    2,  // [] jpg 
    3,  // [] png 
    6   // [] bmp 
); 
if (!in_array($type, $allowedTypes)) { 
  continue;
} 
switch ($type) { 
    case 1 : 
        $im = imageCreateFromGif($filepath); 
        $fun = "imagegif";
    break; 
    case 2 : 
        $im = imageCreateFromJpeg($filepath); 
        $fun = "imagejpeg";
    break; 
    case 3 : 
        $im = imageCreateFromPng($filepath); 
        $fun = "imagepng";
    break; 
    case 6 : 
        $im = imageCreateFromBmp($filepath); 
        $fun = "imagewbmp";
    break; 
} 
 $width = imagesx( $im );
$height = imagesy( $im );

// 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 
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
$fun( $tmp_img, "{$pathToThumbs}{$fname}" );

echo '<div class="thumbnail with-caption">';
echo '<img src="'.$pathToThumbs.$fname.'" class="img-rounded">';
echo '</div>'; 
  }
// close the directory
closedir( $dir );
}

thanks for your help, starlion.
That function returned nothing though
So I made a few modifications, (the functions in the switch statements were all lowercase, the last function should of had a w before the bmp? And is the function exif_imagetype() right)

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

// loop through it, looking for any/all files:
foreach (glob($pathToImages."/*.(jpg,jpeg,gif,png,bmp") AS $image) {
$type = exif_imagetype($image); //  if you don't have exif you could use getImageSize() 
$allowedTypes = array( 
  1,  // [] gif 
  2,  // [] jpg 
  3,  // [] png 
  6   // [] bmp 
); 
if (!in_array($type, $allowedTypes)) { 
continue;
} 
switch ($type) { 
  case 1 : 
	  $im = imagecreatefromgif($filepath); 
	  $fun = "imagegif";
  break; 
  case 2 : 
	  $im = imagecreatefromjpeg($filepath); 
	  $fun = "imagejpeg";
  break; 
  case 3 : 
	  $im = imagecreatefrompng($filepath); 
	  $fun = "imagepng";
  break; 
  case 6 : 
	  $im = imagecreatefromwbmp($filepath); 
	  $fun = "imagewbmp";
  break; 
} 
$width = imagesx( $im );
$height = imagesy( $im );

// 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 
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
$fun( $tmp_img, "{$pathToThumbs}{$fname}" );

echo '<div class="thumbnail with-caption">';
echo '<img src="'.$pathToThumbs.$fname.'" class="img-rounded">';
echo '</div>'; 
}
// close the directory
closedir( $dir );
}

Define ‘returned nothing’. Did you get empty div’s? 404’d images? A White Screen of Syntax Error? An error message?

Heres the page,


I click the Generate Thumbnails link and am taken here

which is only the HTML part of the page,
Also because the echo statements didn’t print anything.

your glob invocation isn’t correct. Check post #4 again.

made a change to

foreach (glob($pathToImages."*.{jpg,jpeg,gif,png,bmp}") AS $image) {

All the ) match up and the different extensions have ,s and are surrounded by {}, is it ok that I changed the variable from $jpg, to $image?

when I change it like this

foreach (glob($pathToImages."/*.{jpg,jpeg,gif,png,bmp}", GLOB_BRACE) AS $image) {

I get images with a screwed up src

<img src="../providers/1/thumbs/" class="img-rounded">

but the thumbs directory has nothing in it though

well that would be because $fname isnt defined in your code anymore.

ok, think im on to something here…
I changed the foreach to

foreach (glob($pathToImages."/*.{jpg,jpeg,gif,png,bmp}", GLOB_BRACE) AS $image) {
$type = exif_imagetype($image); //  if you don't have exif you could use getImageSize() 
$allowedTypes = array( 
  1,  // [] gif 
  2,  // [] jpg 
  3,  // [] png 
  6   // [] bmp 
); 
if (!in_array($type, $allowedTypes)) { 
continue;
} 
switch ($type) { 
  case 1 : 
	  $im = imagecreatefromgif($image); 
	  $fun = "imagegif";
  break; 
  case 2 : 
	  $im = imagecreatefromjpeg($image); 
	  $fun = "imagejpeg";
  break; 
  case 3 : 
	  $im = imagecreatefrompng($image); 
	  $fun = "imagepng";
  break; 
  case 6 : 
	  $im = imagecreatefromwbmp($image); 
	  $fun = "imagewbmp";
  break; 
} 
$width = imagesx( $im );
$height = imagesy( $im );

// 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 
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
$fun( $tmp_img, "{$pathToThumbs}{$im}" );
echo $im;
echo '<div class="thumbnail with-caption">';
echo '<img src="'.$pathToThumbs.$im.'" class="img-rounded">';
echo '</div>'; 
echo "\n";
}

ran the page, got


So at least thats different
is my switch statement right and the imgcopyresized() correct?

So $im is an object - a resource, specifically. Using it as a file name isnt going to help you - the toString method of the object will just return it’s Resource identifier (which is non-unique beyond a single execution of the script). What you need is to take $image, find the image name portion of it (hint: [FPHP]basename[/FPHP]), and tack that onto the end of your thumbs directory to save the file as the appropriate file name.

Then you can use the img tag with that filename/path.

ok made some changes to the code

...
	$width = imagesx( $im );
$height = imagesy( $im );

//find name of new image
$new_image = basename($image);

// 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 
imagecopyresized( $tmp_img, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
$fun( $tmp_img, "{$pathToThumbs}{$new_image}" );
echo $new_image;
echo '<div class="thumbnail with-caption">';
echo '<img src="'.$pathToThumbs.$new_image.'" class="img-rounded">';
echo '</div>'; 
echo "\n";
}

the result


so the images are being generted (but they ared all black) So the problem must be inside the imagecopyresized()

think I found the problem,
when I run it with

error_reporting(E_ALL | E_NOTICE);
ini_set('display_errors', '1');

I get
Warning: imagecopyresized() expects parameter 1 to be resource, string given in /home/luke69/public_html/admin/generate_thumbnails.php on line 102

Thanks for bearing with me on this…
Changed the code

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

// loop through it, looking for any/all files:
foreach (glob($pathToImages.“/*.{jpg,jpeg,gif,png,bmp}”, GLOB_BRACE) AS $image) {
$type = exif_imagetype($image); // if you don’t have exif you could use getImageSize()
$allowedTypes = array(
1, // gif
2, // jpg
3, // png
6 // bmp
);
if (!in_array($type, $allowedTypes)) {
continue;
}
switch ($type) {
case 1 :
$im = imagecreatefromgif($image);
$fun = “imagegif”;
break;
case 2 :
$im = imagecreatefromjpeg($image);
$fun = “imagejpeg”;
break;
case 3 :
$im = imagecreatefrompng($image);
$fun = “imagepng”;
break;
case 6 :
$im = imagecreatefromwbmp($image);
$fun = “imagewbmp”;
break;
}
$width = imagesx( $im );
$height = imagesy( $im );

//find name of new image
$new_image = $pathToThumbs.basename($image);
//echo $image." : ".$new_image;

// 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 
imagecopyresized(  $tmp_img,$im, 0, 0, 0, 0, $new_width, $new_height, $width, $height );

// save thumbnail into a file
$fun( $tmp_img, $new_image );
echo "Dest:".$tmp_img.": Src:".$im;
echo '<div class="thumbnail with-caption">';
echo '<img src="'.$new_image.'" class="img-rounded">';
echo '</div>'; 
echo "\n";
}
// close the directory
closedir( $dir );
}

the result


I didn’t get an error this time, but why the black boxes?

This topic was automatically closed 91 days after the last reply. New replies are no longer allowed.