Jump to content

SOLVED: Generate image variation on upload (client-side image resizing)


Clément Lambelet
 Share

Recommended Posts

Hi all,

 

I'm really new to ProcessWire, maybe I missed the solution in the documentation.

I'm working on a site which involves a lot of image upload fields, and I'm always getting many timeout errors. I'm pretty sure it's because I generate too many variations on a single page load (around 20 images with 7 different sizes, for them to be responsive).

I can't use ImageSizerEngineIMagick to help (my host doesn't support it).

 

I was wondering if there was a way to hook to the process of client-side image resizing (https://processwire.com/blog/posts/processwire-3.0.63-adds-client-side-image-resizing/) to generate the different variations (as it seems really faster). If not, is there a way to generate the different variations on upload and not on page load ?

 

Any ideas and suggestions are welcome!

Edited by Clément Lambelet
Solved (not the best way…)
Link to comment
Share on other sites

Hi Clément and welcome to the forums.

I'm not sure about hooks, but I just wanted to mention that each variation you use in your templates, is only generated once - when you first visit the page in the frontend. Every subsequent frontend visit to that page will load much faster, since PW checks if an image variation exists or not.

re: timeout errors: Are they occuring in the backend?

Link to comment
Share on other sites

Hi dragan,

thanks for your message.

I don't have any timeout error in the backend (or any error at all for that matter).

I saw that the variations are only generated once, but I'm still losing a lot of time to generate them. The last page I created had 15 pictures and it took about 7 minutes to generate all the variations (7 timeout errors). It kind of break my workflow to have to wait that much and it  really slows every other pages (which will be bad once I want to add pages to the public site).

 

Should I try to have less variations? It seems to me that for responsive images (srcset), it's okay to have 7 different sizes.

I would really prefer to have a way to generate them via the client-side image resizing script.

Link to comment
Share on other sites

What you describe here is far, far away from what can be expected in a somewhat "normal" server / hosting setup.

If you can share a link to such pages, we could have a look at it. Or you could do this yourself - open the same page you opened as PW admin in FF/Chrome "anonymous mode".

You mentioned that IMagick is not allowed/installed on your server. Are you aware of any other server-side restrictions? Can you define custom settings via .htaccess, php.ini, user.ini or in php files with ini_set()?

Quote

I would really prefer to have a way to generate them via the client-side image resizing script.

I'm afraid someone else has to look into this (relatively new) method and check if there are options...

  • Like 1
  • Thanks 1
Link to comment
Share on other sites

Thanks for your help.

FYI, here's some server config I could find:

PHP version 		7.1
max_execution_time 	60 seconds
memory_limit 		640 Mo

I can modify .htaccess, but can't change php.ini or user.ini.

I could try to use ini_set() in a php file, but don't know what to put.

I will ask my host (infomaniak), if it would be possible to add IMagick.

 

As for the pages, they are quite simple: https://c-lambelet.com/new/en/projects/collateral-visions/

Here's the code responsible to generate the variations (excerpt):

$options = array(
  'quality' 	=> 71,
  'upscaling' 	=> false,
  'cropping' 	=> false,
  'sharpening' 	=> 'none'
);
		
if($size == 1) { // context specific, here's means full width of browser window
    $i400 = $image->width(400, $options);
	$i800 = $image->width(800, $options);
	$i1200 = $image->width(1200, $options);
	$i1600 = $image->width(1600, $options);
	$i1850 = $image->width(1850, $options);
	$i2250 = $image->width(2250, $options);
	$i2650 = $image->width(2650, $options);
	$i2880 = $image->width(2880, $options);
			
	$markup = '<img src="'.$domain.$i400->url.'"
					srcset="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw=="
					data-srcset="'.$domain.$i400->url.' 400w,
								'.$domain.$i800->url.' 800w,
								'.$domain.$i1200->url.' 1200w,
								'.$domain.$i1600->url.' 1600w,
								'.$domain.$i1850->url.' 1850w,
								'.$domain.$i2250->url.' 2250w,
								'.$domain.$i2650->url.' 2650w,
								'.$domain.$i2880->url.' 2880w"
					data-sizes="auto"
					class="lazyload"
					alt="'.$alt.' - © Clément Lambelet">';
}

---

14 hours ago, dragan said:
Quote

I would really prefer to have a way to generate them via the client-side image resizing script.

I'm afraid someone else has to look into this (relatively new) method and check if there are options...

Anyone would have an idea for this hook? I would be really interested for other uses as well (like auto tagging of the image).

Link to comment
Share on other sites

  • 2 weeks later...

Hi all,

 

thanks @bernhard for this idea. I didn't know how to implement wire-queue properly.

So I went with a more simple way (for myself) which was to modify InputFieldImage.js (in wire/modules) , and make an ajax call to a script which resize the images.

I'm pretty sure it's not the best way to do that, but it's working better (the server seems to handle the resize better if it's from different requests).

It takes around 10 sec to generate the 7 sizes (with GD) compare to a 60 seconds timeout before.

 

Thanks for the help. I will mark the topic as solved.

  • Like 1
Link to comment
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
 Share

  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By spercy16
      These issues should be fairly easy for any intermediate to advanced ProcessWire developer to answer. I'm new to PHP and relatively new to ProcessWire and just need a bit of help. What I'm trying to do is bring in a couple of cards from my Projects page to display on my home page. I finally got the code right to bring in the cards but right now they're using my original images instead of my resized "variations". So firstly, I would like to know how to reference the variations of my images instead of using the original. Secondly, I need to grab only four of the cards from the Project page and not import in all ten. It should be just two small changes to my code to do these things (I would imagine). Here is the code I currently have for that section:
      <?php // https://processwire.com/api/arrays/ // check if the array of images has items if (count($pages->get("/projects/")->images)) : // get array of images from the field $images = $pages->get("/projects/")->images; $count = 0; // iterate over each one foreach ($images as $image) : $count++; $sectionText = $pages->get("/projects/")->get("paragraph_$count"); $img = $image; $buttonCode = $pages->get("/projects/")->get("url_$count"); ?> <span id="card<?php echo $count?>" class="card"> <img class="cardThumb" src="<?php echo $img->url; ?>" alt="<?php echo $image->description; ?> Thumbnail" /> <div class="cardBody"> <div class="cardText"> <h2><?php echo $img->description; ?></h2> <?php echo $sectionText; ?> </div> <div class="primaryBtn"> <a href="https://www.paypal.com/donate?hosted_button_id= <?php echo $buttonCode; ?> &source=url"> <button> <i class="fas fa-donate"></i> Donate </button> </a> </div> </div> </span> <?php endforeach; endif; ?> Thanks in advance for any help!
    • By picarica
      so hello there i have fiel field type i have lots of stuff there, and also an image i can easily get image from that field using
                                                        
      $options = array('quality' => 85, 'upscaling' => true, 'cropping' => 'north', 'sharpening' => 'medium'); $word = ".png"; // Test if string contains the word foreach($childgames->subor_hry as $file) { if(strpos($file, $word) !== false){ /* $imger = $file->size(473, 266, $options); */ echo $file; /* echo $file->url; */ } } so i get the fiel i tried invoking size on it like the commented out part and it doesnt work i get error Oh snizzle… Error:     Exception: Method Pagefile::size does not exist or is not callable in this context (in
      what am i doing wrong? can you guys help me by all logic this should work
    • By Max Esnée
      Hi,
      When I upload a large(ish) SVG (≈120ko in this case) into an image field, it tends to get stuck at 100% and block the whole website. If I force refresh the admin page, the svg has not been uploaded. The file is correctly copied into the assets folder though. Other svg tends to be uploaded fine albeit I've noticed that pages containing svg images in the admin are very slow to load generally. Other pages using the same template but with jpeg or png images are much faster to load.
      I get the following error in the JS console:

      I develop locally using MAMP on macOS and I'm using Firefox. I'm using the last ProcessWire version (3.0.165).
      I also tested in Chrome and got the same error.
    • By dalibor
      I'm using hook for retrieving data from image metadata (IPTC) after image upload and filling them to some fields. When I choose server-side image resize, everything works well. But when I use client-side resize (which si much faster and client comfortable  - it uses PWImageResizer.js) image metadata are lost during resizing - I have downloaded the file after resize and checked for EXIF, IPTC etc. and they are not present.  Using PW 3.0.165. Tried to look into PWImageResizer.js but uhh it's too javascreepy to me:) 
    • By Marvin
      Hello, my name Marvin, i want to ask something. I'm new at processwire, and still learn it, i try yo showing an image, at a table, the image was show, but i can't resize the image
      please HELP
      Here i attach, my code belor
      <?php $num = 1; foreach($pages->get("/files/")->children as $child) { $current = $child === $page ? " class='current'" : ''; $result = $child->images; // $result->width(900); // $result->height(100); foreach($result as $items){ foreach($pages->get($child->name)->files as $file) { // $file = $child->files; // echo $file->name; echo "<tr><td>".$num++.".</td><td>".$child->title."</td><td>".$child->text_1."</td><td>".$child->text_2."</td><td>".$child->text_3."</td><td><a href='".$file->httpUrl."'>".$file->name."</a></td><td><img src='".$items->url."'></td></tr>"; } } } ?>  
×
×
  • Create New...