John Lillard
John Lillard

Reputation: 23

PHP imagecopyresampled() can't seem to output result

I'm trying to read a directory of .jpg files from a folder ./gallery/, make them a bit smaller, and then save them back to ./gallery/_thumbs/.

Everything seems to work up until I try to use the imagecopyresampled() to actually do the resizing. The PHP man says it should return a bool on success/failure, but I'm able to get anything and hence don't know what I'm doing wrong.

I'm assuming that if I get a valid result from imagecopyresampled() that the imagejpeg() will work okay the way I have it?

for($i=0;$files_in_dir[$i]!=null;$i++)
{
   if (!($files_in_dir[$i]=="."||$files_in_dir[$i]==".."||$files_in_dir[$i]=="_thumb"))
   {
      $my_images['image_name']=$files_in_dir[$i];
      $my_images['path_to_current']=$directory.$my_images['image_name'];
      $my_images['path_to_finished_thumb']=$directory.$sub_directory.$prefix.$my_images['image_name'];
      $my_images['image_handler']=imagecreatefromjpeg($my_images['path_to_current']);
      $imagesize = getimagesize($my_images['path_to_current']);
      $my_images['width']=$imagesize[0];
      $my_images['height']=$imagesize[1];
      $my_images['ratio']=$my_images['height']/$my_images['width'];
      $my_height = round($my_width / $ratio);
      echo "<pre>";
      var_dump($my_images);
      $newImage = imagecreatetruecolor($my_width,$my_height);
      $success = imagecopyresampled($newImage,$my_images['image_handler'],0,0,0,0,$my_width,$my_height,$my_images['width'],$my_images['height']);
      echo "my success was: ",$success,"<br />";
      imagejpeg($newImage,$my_images['path_to_finished_thumb'],80);
      imagedestroy($my_images['image_handler']);
      imagedestroy($newImage);
      echo "</pre>";
   }
}
?>

Upvotes: 0

Views: 1331

Answers (1)

beporter
beporter

Reputation: 3970

There are a couple things to come to mind.

  1. First, check to make sure PHP is able to write to the files and directories in question.

  2. Make sure you're seeing all errors/warnings so you know when something fails.

  3. From your report it certainly sounds like your copy of PHP has the GD extension installed, but do make sure before you assume that extension-based functions like imagejpeg() are available. You can use a page containing <?php phpinfo(); to determine this yourself, or you can do it programmatically using function_exists().

I've taken the liberty of streamlining your script to make it easier to catch possible bugs (fewer lines = fewer possible mistakes):

<?php

// Make sure we see processing errors during development/testing.
error_reporting(E_ALL);
ini_set('display_errors', true);

// Set up operating parameters.
$filePattern = 'gallery/*.[jJ][pP][gG]';
$thumbPattern = 'thumbs/%s';
$targetWidth = 200;
$targetQuality = 80;

// Create the output dir, if it doesn't already exist. This will fail
// if PHP does not have write access to the local folder.
$thumbDir = sprintf($thumbPattern, '');
if (!is_dir($thumbDir)) {
    mkdir($thumbDir);
}

// Abort if GD is not installed.
if (!function_exists('imagejpeg')) {
    die('PHP does not have the GD extension installed. Aborting.');
}

// Abort if the output directory is not writable.
if (!is_writable($thumbDir)) {
    die('The output directory is not writable by PHP. Check permissions. Aborting.');
}

// Loop over all found jpg files.
foreach (new GlobIterator($filePattern) as $f) {

    // var_dump($f->getRealpath()); // Debugging the path name.

    // Skip regenerating cached thumbs for performance.
    $thumbPath = sprintf($thumbPattern, $f->getFilename());
    if (file_exists($thumbPath)) {
        continue;
    }

    // Determine thumbnail output size.
    list($w, $h) = getimagesize($f->getRealpath());
    $ratio = $h / $w;
    $targetHeight = round($targetWidth * $ratio);

    // Generate the thumbnail from the original.
    $jpg = imagecreatefromjpeg($f->getRealpath());
    $thumb = imagecreatetruecolor($targetWidth, $targetHeight);
    $success = imagecopyresampled(
        $thumb,
        $jpg,
        0, 0, 0, 0,
        $targetWidth, $targetHeight, $w, $h
    );
    imagejpeg($thumb, $thumbPath, $targetQuality);
}

(Gist version here.)

One thing I caught during this process was that the logic for determining the thumbnail ratio was reversed. It needs to be $targetWidth * $ratio (instead of $targetWidth / $ratio).

This version of the script doesn't do the same naming manipulation-- it just creates a new thumbs/ folder wherever the script lives and saves the thumbnail versions from gallery/ into it.

Upvotes: 2

Related Questions