Brian Scramlin

How Image Resizing Works

8 posts in this topic

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

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

1 person likes this

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

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
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:

 

2 people like this

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 louisstephens
      I have been scratching my head on this one for a while, so I thought maybe someone could shed some light on this issue. I am using a grid layout (that I have created over the years) with a class for responsive images (very similar to bootstrap, but very stripped down). Using this, I created a gallery using a foreach loop, and included a "print button" to print each image. I got the classes and everything worked out, but I ran into a small problem with the print functionality. My images (which are around 2400px wide to fill the space) are just fine in the grid and on resize, but when I print, they "run off" the page. I understand that they are just too big to be printed in portrait mode, which led to me think that I could use $image->size(); to print a scaled down version of the image (which adds a bit more load time as now the site needs to load the image large scale and the scaled down version). However, I can't seem to wrap my head around serving just the scaled down version for print only (obviously display:none; doesn't do the trick). Has anyone tackled this before, or does anyone know of a more elegant solution to the conundrum that I have found myself in?
      The Foreachloop:
      $printclass = 1; foreach($page->galleries as $gallery) { $printclass++; $printimage = $gallery->gallery_image->width(600)->url; $out = ""; $out .= "<div class=\"row\">"; $out .= "<div class=\"grid-12\">"; $out .= "<img src=\"{$gallery->gallery_image->url}\" class=\"reimage\"/>"; $out .= "</div>"; $out .= "</div>"; $out .= "<div class=\"row\">"; $out .= "<div class=\"grid-12\">"; $out .= "<a href=\"#\" onClick=\"printCoupon('printable{$printclass}');\">Print</a>"; $out .= "</div> "; $out .= "</div> "; $out .="<div id=\"printable{$printclass}\"><img src=\"{$printimage}\"/></div>"; echo $out; }  
       
    • By billjoseph
      Weirdest thing just happened to me.  I updated blank site from 3.0.42 to 3.0.61 then started adding fields.  I have two instances of FieldsetOpen areas in the template, and a few CKEditor textareas (both inside those fieldsets and outside). 
      I added an image field to the template and placed it near the top of the template fields.  Once I did that I was unable to toggle either Fieldset, and the CKEditor stopped working.
      When I moved the image field to the bottom of the template fields, the CKEditor loaded, but the fieldsets still wouldn't toggle.  When I deleted the image field, the editor and toggle return to normal.  (Adding a new image field re-introduces the issues.)
      I've tried adjusting the settings on the image field but the result is the same - even with all default settings.  I tried adding an image field to a different template - same result.
      What am I missing here?
    • By horst
      Hi, here is a very useful tool that check your images in websites against responsiveness:
      https://github.com/ausi/respimagelint
       

    • By evanmcd
      Hi all,
      I've not been able to upload SVGs into a regular image field, with SVG added in the Valid File Extensions field.
      The error I'm getting is:
      Error: Call to undefined function ProcessWire\simplexml_load_string() (line 234 of /var/www/hosts/our_website/Develop/Source/wire/core/Pageimage.php) I tried the ImageRasterizer module, but that didn't fix it.
      Is there a workaround for folks that don't have the simplexml module installed?
    • By Ibrahim El Haddad
      Hi guys, 
      Yesterday, I faced a problems to run a processwire old system from backup locally, finally after your support, the system start working but still I have the below problems issues. 
      1. Once I try to press a sub-link, it guides me to Object not found, Error 404  similar to the below , and the link of the website became like below: 
      http://www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.localhost:9999/publications-and-ressources/texts/books/
      despite of that my application name is ibrahem, so if I amend the url manually to be as 
      http://www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.www.localhost:9999/ibrahem/publications-and-ressources/texts/books/
      it works fine, but every link, i should amend the url to add the application name. 
      Object not found!
      The requested URL was not found on this server. The link on the referring page seems to be wrong or outdated. Please inform the author of that page about the error.
      If you think this is a server error, please contact the webmaster.
      Error 404
       
      2. The images issues, that the images related to the book cover or another issue such as the slider is not appear, please advice.
       
      Thank you in advance for all of your support and help.