Image Resizing Script required - a better one...

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Image Resizing Script required - a better one...

Post by Celauran »

That's part of it. You also need to have the function return the name of the new image and store that in a variable which you will then pass to your database query.
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

I thought that was $new_filename ?
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Image Resizing Script required - a better one...

Post by Celauran »

simonmlewis wrote:I thought that was $new_filename ?
Where is $new_filename?
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

Code: Select all

// Resizes a single image to a specific size and with a specific suffix
function resizeSingleImage($original, $suffix, $width, $save_path)
{
    $imagine = new Imagine\Gd\Imagine();

    $target_directory = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . $save_path;
    $pathinfo = pathinfo($original);

    // Open the uploaded image with the Imagine library
    $image = $imagine->open($target_directory . DIRECTORY_SEPARATOR . $original);

    // Get the size of the original image
    $box = $image->getSize();

    $ratio = $width / $box->getWidth();
    $scaled_box = $box->scale($ratio);

/// HERE ///
    $new_filename = "{$pathinfo['filename']}_{$suffix}.{$pathinfo['extension']}";

    $options = getImageOptions($pathinfo['extension']);
    $image->resize($scaled_box)->save($target_directory . DIRECTORY_SEPARATOR . $new_filename, $options);
}
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Image Resizing Script required - a better one...

Post by Celauran »

Two things here. We're calling resizeImage, not resizeSingleImage. More importantly, that variable only exists within the scope of the function in which it is defined. If you want to use it elsewhere, you need to return it and capture it in a variable.

Code: Select all

// Takes input from a form post and saves original image plus all required resizes
function resizeImage($path_to_file, $file_name, $resize_type)
{
    $imagine = new Imagine\Gd\Imagine();

    $target_directory = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . 'pages';
    $pathinfo = pathinfo($file_name);
    $prefix = time();

    // Open the uploaded image with the Imagine library
    $image = $imagine->open($path_to_file);

    // Save the original
    $options = getImageOptions($pathinfo['extension']);
    $path_to_original = $target_directory . DIRECTORY_SEPARATOR . "{$prefix}{$pathinfo['basename']}";
    $image->save($path_to_original, $options);

    // Resize

    // Get the size of the original image
    $box = $image->getSize();

    // Get the sizes we need
    $widths = getWidths($resize_type);

    // Create resized images
    foreach ($widths as $key => $width) {
        $ratio = $width / $box->getWidth();
        $scaled_box = $box->scale($ratio);
        $new_filename = "{$prefix}{$pathinfo['filename']}_{$key}.{$pathinfo['extension']}";

        // Re-open the original for scaling so we're not creating a larger image from a smaller
        $source = $imagine->open($path_to_original);
        $source->resize($scaled_box)->save($target_directory . DIRECTORY_SEPARATOR . $new_filename, $options);
    }

    // We don't want the full path, just the file name
    return "{$prefix}{$pathinfo['basename']}";
}
So that handles returning the file name. Now we need to store it in a variable.

Code: Select all

// If we have an uploaded image without errors
if (!empty($_FILES) && isset($_FILES['homeimage'])) {
    $saved_filename = resizeImage($_FILES['homeimage']['tmp_name'], $_FILES['homeimage']['name'], $resize);
}
Finally, we can use $saved_filename in the DB query.
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

So more like this.
Function runs. Gathers the info.
Outputs the new filename that's been uploaded via function, and adds it to the database.

Code: Select all

require_once '/functions/functionConsumerResize.php';
// If we have an uploaded image without errors
if (!empty($_FILES) && isset($_FILES['homeimage'])) {
    $saved_filename = resizeImage($_FILES['homeimage']['tmp_name'], $_FILES['homeimage']['name'], $resize);
}

    if ($searchurl != "")
  {
  mysql_query("INSERT INTO homepage(url, image, section, freetext, priority, content, homepromocolor, homepromotextcolor, stockbanner) VALUES ('$searchurl', '$saved_filename', '$section', '$freetext', '$priority', '$content', '$homepromocolor', '$homepromotextcolor', '$stockbanner')");
  }
  elseif ($searchurl == "")
  {
  mysql_query("INSERT INTO homepage(url, image, section, freetext, priority, content, homepromocolor, homepromotextcolor, stockbanner) VALUES ('$url', '$saved_filename', '$section', '$freetext', '$priority', '$content', '$homepromocolor', '$homepromotextcolor', '$stockbanner')");
  }

  //Writes the photo to the server
  if(move_uploaded_file($_FILES['homeimage']['tmp_name'], $target))
    {
echo "<script>
  window.location.replace('/a_home')
  </script>";
    }
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Image Resizing Script required - a better one...

Post by Celauran »

Looks good. Now you just need to get rid of that call to move_uploaded_file.
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

Ok. IT doesn't like this about 6 lines from the bottom of the functions file.

$new_filename = "{$pathinfo['filename']}_{$suffix}.{$pathinfo['extension']}";
Unexpected {.
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Image Resizing Script required - a better one...

Post by Celauran »

simonmlewis wrote:Ok. IT doesn't like this about 6 lines from the bottom of the functions file.

$new_filename = "{$pathinfo['filename']}_{$suffix}.{$pathinfo['extension']}";
Unexpected {.
Can you post the current contents of the file?
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

Code: Select all

<?php
require_once '/vendor/autoload.php';

// Returns required quality settings for Imagine based on image's extension
function getImageOptions($extension)
{
    switch ($extension) {
        case 'jpg':
        case 'jpeg':
            $options = array('jpeg_quality' => 97);
            break;
        case 'png':
            $options = array('png_compression_level' => 8);
            break;
        default:
            $options = array();
    }

    return $options;
}

function getSrcSet($filename, $resize_type = 'wide')
{
  switch($resize_type) {
      case 'stockbanners':
      $actualfolder = 'stockbanners';
      break;
      case 'thumbnails':
      $actualfolder = 'productphotos/small';
      break;
      default:
      $actualfolder = 'pages';
      break;
     }
    $root_directory = dirname(__DIR__);
    $images_directory = DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . $actualfolder;
    $images_path = "/images/{$actualfolder}"; // Still need this for srcset output
    $source_directory = $root_directory . $images_directory;
    $srcset = array();

    $widths = getWidths($resize_type);

    if (file_exists($source_directory . DIRECTORY_SEPARATOR . $filename)) {
        $basename = pathinfo($filename, PATHINFO_FILENAME);
        $extension = pathinfo($filename, PATHINFO_EXTENSION);

        foreach ($widths as $size => $width) {
            $fullname = $basename . '_' . $size . '.' . $extension;
            if (file_exists($source_directory . DIRECTORY_SEPARATOR . $fullname)) {
                $srcset[] = "{$images_path}/{$fullname} {$size}w";
            } else {
                resizeSingleImage($filename, $size, $width, $actualfolder);
                $srcset[] = "{$images_path}/{$fullname} {$size}w";
            }
        }
    }

    return implode(', ', $srcset);
}

// Returns an array of widths, keyed by target screen size
function getWidths($resize_option)
{
    switch($resize_option) {
        case 'categories':
        case 'products':
        case 'stockbanners':
            $widths = array(
                '475' => 237,
                '768' => 384,
                '1920' => 451,
            );
            break;
        case 'wide':
            $widths = array(
                '475' => 237,
                '768' => 384,
                '1920' => 950,
            );
            break;
        case 'desktopslide':
            $widths = array(
                '475' => 475,
                '768' => 768,
                '1920' => 1920,
            );
            break;
        case 'thumbnails':
            $widths = array(
    '475' => 237,
    '768' => 384,
    '1920' => 451,
    '2520' => 600,
            );
            break;            
        default:
            $widths = array();
            break;
    }

    return $widths;
}

// Takes input from a form post and saves original image plus all required resizes
function resizeImage($path_to_file, $file_name, $resize_type)
{
    $imagine = new Imagine\Gd\Imagine();
    
  switch($resize_type) {
      case 'stockbanners':
      $actualfolder = 'stockbanners';
      break;
      case 'thumbnails':
      $actualfolder = 'productphotos/small';
      break;
      default:
      $actualfolder = 'pages';
      break;
     }
    
    $target_directory = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . $actualfolder;
    $pathinfo = pathinfo($file_name);
    $prefix = time();

    // Open the uploaded image with the Imagine library
    $image = $imagine->open($path_to_file);

    // Save the original
    $options = getImageOptions($pathinfo['extension']);
    $path_to_original = $target_directory . DIRECTORY_SEPARATOR . "{$prefix}{$pathinfo['basename']}";
    $image->save($path_to_original, $options);

    // Resize

    // Get the size of the original image
    $box = $image->getSize();

    // Get the sizes we need
    $widths = getWidths($resize_type);

    // Create resized images
    foreach ($widths as $key => $width) {
        $ratio = $width / $box->getWidth();
        $scaled_box = $box->scale($ratio);
        $new_filename = "{$prefix}{$pathinfo['filename']}_{$key}.{$pathinfo['extension']}";

        // Re-open the original for scaling so we're not creating a larger image from a smaller
        $source = $imagine->open($path_to_original);
        $source->resize($scaled_box)->save($target_directory . DIRECTORY_SEPARATOR . $new_filename, $options);
    }
    return "{prefix}{$pathinfo['basename']};
}

// Resizes a single image to a specific size and with a specific suffix
function resizeSingleImage($original, $suffix, $width, $save_path)
{
    $imagine = new Imagine\Gd\Imagine();

    $target_directory = dirname(__DIR__) . DIRECTORY_SEPARATOR . 'images' . DIRECTORY_SEPARATOR . $save_path;
    $pathinfo = pathinfo($original);

    // Open the uploaded image with the Imagine library
    $image = $imagine->open($target_directory . DIRECTORY_SEPARATOR . $original);

    // Get the size of the original image
    $box = $image->getSize();

    $ratio = $width / $box->getWidth();
    $scaled_box = $box->scale($ratio);
    $new_filename = "{$pathinfo['filename']}_{$suffix}.{$pathinfo['extension']}";

    $options = getImageOptions($pathinfo['extension']);
    $image->resize($scaled_box)->save($target_directory . DIRECTORY_SEPARATOR . $new_filename, $options);
}

?>
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

I See the issue. I have repaired it.
But the thing is still doesn't do is to add the entry now into the database.
Images are resizing and renaming.

Correction: it is doing the process... TWICE!
So I have SIX files now. 2 of each. And it is inserting this into the database:
[text]{prefix}prod-test.jpg[/text]

Quote or missing quotes somewhere?
Last edited by simonmlewis on Mon Mar 13, 2017 9:43 am, edited 1 time in total.
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Image Resizing Script required - a better one...

Post by Celauran »

Still sounds like progress. Let's see what your upload script looks like now. Also, are you getting any errors?
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

Please see last comment.
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
User avatar
Celauran
Moderator
Posts: 6427
Joined: Tue Nov 09, 2010 2:39 pm
Location: Montreal, Canada

Re: Image Resizing Script required - a better one...

Post by Celauran »

simonmlewis wrote:Correction: it is doing the process... TWICE!
So I have SIX files now. 2 of each. And it is inserting this into the database:
[text]{prefix}prod-test.jpg[/text]

Quote or missing quotes somewhere?
Well that's unexpected. Again, let's take a look at the upload script. If it's running everything twice, it's because the resizeImage function is being called twice. Have you checked the return value of resizeImage?
simonmlewis
DevNet Master
Posts: 4435
Joined: Wed Oct 08, 2008 3:39 pm
Location: United Kingdom
Contact:

Re: Image Resizing Script required - a better one...

Post by simonmlewis »

Ok now got this error in the logs.

[text]mod_fcgid: stderr: PHP Warning: require_once(/vendor/autoload.php): failed to open stream: No such file or directory in /var/www/vhosts/site.co.uk/subdomains/sand.site.co.uk/httpdocs/functions/functionConsumerResize.php on line 2, referer: http://sand.site.co.uk/a_home[/text]

It's in the functions file like so:

require_once '/vendor/autoload.php';

Maybe it should be there differently.. with DIR ??
Love PHP. Love CSS. Love learning new tricks too.
All the best from the United Kingdom.
Post Reply