Brian Scramlin

How Image Resizing Works

Recommended Posts

Hey Everyone,

I have a question that seems like it would have an obvious answer, but I cannot wrap my mind around it:

If I have 

<img src="<?= $page->featuredImage->size(800,500)->url ?>"/>

in an article template, does my server run a resizing script

  • every time someone requests the page?
  • Or, is it resized only the first time it is requested?
  • Or when the page is saved?

The reason I would like to know is because I have created two image processing functions my client requires, but one of them is a paid subscription service to compress the images. I don't want to call the paid API every time a page is loaded or something.

Thanks for fielding my ignorance :P

Share this post


Link to post
Share on other sites
LostKobrakai    4,313

The thumbnail generation does run when this code is executed and the file corresponding to the thumbnail does not exist at that time.

  • Like 1

Share this post


Link to post
Share on other sites

How is it possible for me to run a PHP Function on an image as it is being uploaded? This would be the ideal situation because then anywhere I need to execute the ->size() functions I don't have to re-call my compression service.

Right now all over my website I have something like  tinify($page->image->size(200,200)->url) instead I would rather just have the tinify() function called on the initial save. 

Further, if it was possible to do this for every image including CKEditor body images we would be in business!

Thank you for your help. 

Share this post


Link to post
Share on other sites
LostKobrakai    4,313

There are various topics around this exact use case on the forums. The short version: there's no obvious solution, but things you can do.

Share this post


Link to post
Share on other sites
horst    3,961
1 hour ago, Brian Scramlin said:

How is it possible for me to run a PHP Function on an image as it is being uploaded? This would be the ideal situation because then anywhere I need to execute the ->size() functions I don't have to re-call my compression service.

Right now all over my website I have something like  tinify($page->image->size(200,200)->url) instead I would rather just have the tinify() function called on the initial save. 

Further, if it was possible to do this for every image including CKEditor body images we would be in business!

Thank you for your help. 

Tinifying images is ONLY useful on the final variations. Tinifying an original source image is completly WRONG.

This tinifying is often misunderstood.

You can resize an image on upload to variuos varirations and also tinify them, if you exactly know which variations you will need around in your site.

Here is an example how to hook into upload and process something with the image:

 

  • Like 2

Share this post


Link to post
Share on other sites

Thank you, everyone. I appreciate your input. I understand in most scenarios converting the original file on upload is not the best approach. However, in this situation it seems the best way to save on calling my iMagick function and compression function. 

First off, I have never created a Processwire module and am intimidated by the prospect, but I am considering the suggested InputfieldImageThumbs module route.

Here is the original module:

class InputfieldImageThumbs extends WireData implements Module {

    public function init() {
        $this->addHookAfter('InputfieldFile::fileAdded', $this, 'createThumbs');
    }

    public function createThumbs($event) {
        $inputfield = $event->object;
        $image = $event->arguments("pagefile");
        
        $allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF); // allowed image formats
        $detectedType = exif_imagetype($image->filename); // check if file is an image
        if(!in_array($detectedType, $allowedTypes)) return; // if not, exit

        $widths = explode(",", $this->imageWidths, 10); // convert comma separated list to array, limit to 10 values
        $widths = array_filter($widths, 'ctype_digit'); // keep only numeric entries in the array
        
        foreach($widths as $width) {
            $image->size($width,0); // generate image for each defined width
        }
    }
}

Here is a stab at my attempted module. I am very new at this, so please prepare yourself

class tinifyImages extends WireData implements Module {

    public function init() {
        $this->addHookAfter('InputfieldFile::fileAdded', $this, 'tinify');
    }

    public function tinify($event) {
        $inputfield = $event->object;
        $image = $event->arguments("pagefile");
        
        $allowedTypes = array(IMAGETYPE_PNG, IMAGETYPE_JPEG, IMAGETYPE_GIF); // allowed image formats
        $detectedType = exif_imagetype($image->filename); // check if file is an image
        if(!in_array($detectedType, $allowedTypes)) return; // if not, exit

        /* Include Tinify API Resources and Initialize */
        require_once("inc/tinify-php-master/lib/Tinify/Exception.php");
        require_once("inc/tinify-php-master/lib/Tinify/ResultMeta.php");
        require_once("inc/tinify-php-master/lib/Tinify/Result.php");
        require_once("inc/tinify-php-master/lib/Tinify/Source.php");
        require_once("inc/tinify-php-master/lib/Tinify/Client.php");
        require_once("inc/tinify-php-master/lib/Tinify.php");
        \Tinify\setKey("API_KEY");

        //function used to compress with tinify api 
        function tinify($imagePath) {
            $path_parts = pathinfo($imagePath);
            $dirname = $path_parts['dirname'] . '/';
            $filename = $path_parts['filename'];
            $savename = $dirname . $filename . '-compressed.jpg';
            if (!file_exists($_SERVER['DOCUMENT_ROOT'] . $savename)) {
                $source = \Tinify\fromFile($_SERVER['DOCUMENT_ROOT'] . $imagePath);
                $source->toFile($_SERVER['DOCUMENT_ROOT'] . $savename);
            }
            return $savename;
        }
        
        $image = tinify($image->url);
    }
}
?>

Am I close?

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By rst
      Hello,
      I have repeater field with an image field as one of its fields. It works correctly on all but one templates. I added an image, it shows the image uploading, but then the image just disappears and it doesn't save. What could it be ?
       
      Thanks
    • By Gazley
      Hi there,
      I'm looking to render some square images that are based on portrait originals. When the image is selected, I'll display it in portrait mode but when the images are in a "summary" mode, I want them square. What would be the best way to generate a square image from a portrait original? FYI, I would ideally prefer these images to based on IMG tags and not background images.
      Cheers!
    • By Roberts R
      Solution :
       
      Issue :
      Fresh install ProcessWire 3.0.39 + multilangual support
      In video it shows how it goes. And I can't figure it out.  It happens for few of my sites.
      td;tl : Upload 5 image in images field ->  Save -> 2 left.
      EDIT : Files are in "/assets/files/id"
      processwire-bug.mp4
    • By Andreas Augustin
      Hello!
      I'm struggling with some strange problem. I want to get the description of an image in my template but it is null.
      When I'm dumping the image I see that the value is in a field called description1012. Why?
      object(Image)#396 (2) { ["changes"]=> array(1) { [0]=> string(9) "formatted" } ["data"]=> array(8) { ["basename"]=> string(23) "nbr1052-previewbild.jpg" ["description1012"]=> string(0) "" ["tags"]=> string(0) "" ["formatted"]=> bool(true) ["modified"]=> int(1490190603) ["created"]=> int(1490190603) ["description"]=> NULL ["url"]=> string(72) "http://s7w2p3.scene7.com/is/image/bluetomato/ugc/nbr1052-previewbild.tif" } }