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

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 after a few issues found, I've got it working for the three areas without any issues.

Next is deletion.
This is my current script:

Code: Select all

 // DELETE BANNER
if ($u == "deletebanner") 
{
$result = mysql_query ("SELECT * FROM homepage WHERE id = '$did'");
while ($row = mysql_fetch_object($result))
  {
$filename = $row->image;
$path = $_SERVER['DOCUMENT_ROOT'].'/images/pages/'.$filename;
$fh = fopen($path, 'w');
fclose($fh);
unlink($path);
  }
mysql_free_result($result);
mysql_query ("DELETE FROM homepage where id='$did'");
echo "<script>
  window.location.replace('/a_home')
  </script>";
}
So how do I use $filename as some sort of mask, to delete the 'other' files of the similar filename?
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 have a feeling I have figured it out.
Using your pathinfo code, I separated out the extension from the filename, used this page: (http://php.net/manual/en/function.unlink.php) to work out the masking, and hey presto it works!

Four files go up. And then four files get deleted.

Brilliant. Well chuffed.

Maybe there is a slightly cleaner way to do it, but it looks good to me.

Code: Select all

 // DELETE BANNER
if ($u == "deletebanner") 
{
$result = mysql_query ("SELECT * FROM homepage WHERE id = '$did'");
while ($row = mysql_fetch_object($result))
  {
$filename = $row->image;
$path = $_SERVER['DOCUMENT_ROOT'].'/images/pages/'.$filename;
$fh = fopen($path, 'w');
fclose($fh);
unlink($path);

$pathinfo = pathinfo($filename);

$new_filename = "{$pathinfo['filename']}";
$new_ext = "{$pathinfo['extension']}";

array_map('unlink', glob("images/pages/$new_filename*.$new_ext"));
  }
mysql_free_result($result);
mysql_query ("DELETE FROM homepage where id='$did'");
echo "<script>
  window.location.replace('/a_home')
  </script>";
}
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 »

It seems to be losing A LOT of quality on larger 4K images.
I looked into this, and found this code:
imagejpeg($thumb, $filename."_prev.jpg", 100);
But not sure how I can place this into the existing resize script. Any ideas?
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:It seems to be losing A LOT of quality on larger 4K images.
I looked into this, and found this code:
imagejpeg($thumb, $filename."_prev.jpg", 100);
But not sure how I can place this into the existing resize script. Any ideas?
https://imagine.readthedocs.io/en/lates ... ave-images

You can check for the type of image being saved and create an array containing the relevant quality attributes that you'd pass to the save function.
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:Maybe there is a slightly cleaner way to do it, but it looks good to me.
Looks about right to me as well. Not sure there's much point in fopen immediately followed by fclose, and you could probably extract a function or two to clean things up a little, make it more readable, but on the whole it's the approach I was suggesting. Should work well.
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 »

Celauran wrote:
simonmlewis wrote:It seems to be losing A LOT of quality on larger 4K images.
I looked into this, and found this code:
imagejpeg($thumb, $filename."_prev.jpg", 100);
But not sure how I can place this into the existing resize script. Any ideas?
https://imagine.readthedocs.io/en/lates ... ave-images

You can check for the type of image being saved and create an array containing the relevant quality attributes that you'd pass to the save function.
I just want ALL images to be saved at the original 100%.... ??
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 »

That's fine. Doesn't really change my answer. Have you looked at the documentation? There's a slight difference in how you would achieve that for a JPG vs a PNG, and examples of both are given.
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 »

They are always .jpg.

Code: Select all

$imagine->open('/path/to/image.jpg')
   ->save('/path/to/image.jpg', array('jpeg_quality' => 100)) // from 0 to 100
This looks something like it. So I alter the code of the file path, so it matches mine.
I assume the default setting is a much lower quality.
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 »

Default quality is 75%. Says so in the documentation. You're already calling save, you just need to add that second argument to it.
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 »

Oh. Ok. Not at PC right now. I'll have a go in a little while. IT looks like the reduction in quality on a large image is way more than 75%. For a 2520 wide image down to 1920, the size went down to just 90kb.
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 »

Small file size doesn't need to be a bad thing if the image is optimized. 1920 stood out, though. Look at your early post explaining the three different sizes. You appear to be scaling down an image for 1920px displays to a 451px image. Are you sure you're resizing the images to the correct dimensions?
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 »

Done it - works a treat. Thanks.
You are right about Composer! lol.
Trying to check our live server has it.

And yes that is right, as those banners are 4 across. At the moment they are badly sized at about 800px, which is wastage.
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 »

Looked into it further and I see what's happening. Inside your foreach loop, you'll want to re-open the original that you saved and use that as the basis for your resizing. Example code below. Do not copy/paste. Read and understand.

Code: Select all

// If we have an uploaded image without errors
if (!empty($_FILES) && isset($_FILES['image']) && $_FILES['image']['error'] == 0) {
    $target_directory = __DIR__ . '/images/imagine';
    $pathinfo = pathinfo($_FILES['image']['name']);
    $prefix = time();

    // Open the uploaded image with the Imagine library
    $image = $imagine->open($_FILES['image']['tmp_name']);

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

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

    // Resize
    foreach ($widths as $key => $width) {
        $ratio = $width / $box->getWidth();
        $scaled_box = $box->scale($ratio);
        $new_filename = "{$prefix}-{$pathinfo['filename']}-{$key}.{$pathinfo['extension']}";
        $image = $imagine->open($path_to_original);
        $image->resize($scaled_box)->save($target_directory . '/' . $new_filename, $options);
    }
}
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 »

It's gone back to poor quality again.
Any ideas why?

Code: Select all

// ADD ALL BANNERS (SQUARE AND DOUBLE)
if ($update == "addbanner")
{
  if (isset($layertype))
  {
    $result = mysql_query ("SELECT id FROM products WHERE romancode = '$searchurl'");
    $num_result = mysql_num_rows($result);
    if ($num_result > 1)
    {
    $disableupload = "yes";
    echo "<script>
  window.location.replace('/a_home&status=duplicatecode')
  </script>";
    }
  }
 
  if (!isset($disableupload))
  {
    if ($stockbanner == "yes")
    {
      if ($searchurl != "")
      {
      mysql_query("INSERT INTO homepage (url, section, freetext, priority, content, homepromocolor, homepromotextcolor, stockbanner) VALUES ('$searchurl', '$section', '$freetext', '$priority', '$content', '$homepromocolor', '$homepromotextcolor', '$stockbanner')");
      }
      elseif ($searchurl == "")
      {
      mysql_query("INSERT INTO homepage (url, section, freetext, priority, content, homepromocolor, homepromotextcolor, stockbanner) VALUES ('$url', '$section', '$freetext', '$priority', '$content', '$homepromocolor', '$homepromotextcolor', '$stockbanner')");
      }
      echo "<script>
  window.location.replace('/a_home')
  </script>";
    }
    else
    {
    $target_directory = $_SERVER['DOCUMENT_ROOT']."/images/pages/";
    $random = (rand()%99999999);
    $pic=($_FILES['homeimage']['name']);
    $newname= $random . "_". $pic;
    $target = $target_directory . $newname;
    if ($searchurl != "")
  {
  mysql_query("INSERT INTO homepage(url, image, section, freetext, priority, content, homepromocolor, homepromotextcolor, stockbanner) VALUES ('$searchurl', '$newname', '$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', '$newname', '$section', '$freetext', '$priority', '$content', '$homepromocolor', '$homepromotextcolor', '$stockbanner')");
  }
 
require_once dirname(__DIR__) . '/vendor/autoload.php';
$imagine = new Imagine\Gd\Imagine();

if (isset($resize))
{
  if ($resize == "categories" || $resize == "products")
  {
    // An array of widths, keyed by target screen size
$widths = [
    '475' => 237,
    '768' => 384,
    '1920' => 451,
];
  }
  elseif ($resize == "wide")
  {
  // An array of widths, keyed by target screen size
$widths = [
    '475' => 237,
    '768' => 384,
    '1920' => 950,
];
  }
  elseif ($resize == "desktopslide")
  {
  // An array of widths, keyed by target screen size
$widths = [
    '475' => 475,
    '768' => 768,
    '1920' => 1920,
];
  }  
}

// If we have an uploaded image without errors
if (!empty($_FILES) && isset($_FILES['homeimage'])) {
    $pathinfo = pathinfo($_FILES['homeimage']['name']);

    // Open the uploaded image with the Imagine library
    $image = $imagine->open($_FILES['homeimage']['tmp_name']);

    

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

    // Resize
    foreach ($widths as $key => $width) {

        $ratio = $width / $box->getWidth();
        $scaled_box = $box->scale($ratio);
        
        $new_filename = "{$random}_{$pathinfo['filename']}_{$key}.{$pathinfo['extension']}";
        $image->resize($scaled_box)->save($target_directory . '/' . $new_filename, array('jpeg_quality' => 100));
    }
}
  //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 »

simonmlewis wrote:It's gone back to poor quality again.
Any ideas why?
Celauran wrote:Looked into it further and I see what's happening. Inside your foreach loop, you'll want to re-open the original that you saved and use that as the basis for your resizing.
Post Reply