Jump to content
jacmaes

Webp support

Recommended Posts

Another update to the PageImage class, comes in handy during the webp work. But it is not only useful for WebP copies, but for everything in regards of experimenting and debugging with images. I added a new method: ->getDebugInfo($options). See examples here: https://biriba.de/pw_pop3/pw_pageimage_getdebuginfo/

 

  • Like 4

Share this post


Link to post
Share on other sites

Please can someone test the .htaccess solution for WebP support in other environments?

It is not much work, you don't have to install test branches or anything else. You only need to copy some lines into your .htaccess file and create a single webp image with the tool of your choice. Or if you don't have a converter tool for webp, simply make a copy of a jpeg and rename it with type .webp instead of .jpg.

Steps to proceed:

  1. Copy the rewrite directives into the top of your .htaccess file 
  2. Grab any image variation you already have embedded into a PW site, create a webp variation of and save it into the same assets/files/{ID}/ folder.
    (Maybe you want to invert the colors of the webp copy for better detection!)
  3. Create or go to a page where this image should be rendered as jpeg in a regular img tag, and look if the webp copy is served and displayed.
    (Don't forget to flush browser caches)

The .htaccess code:

Spoiler

AddType image/webp .webp

<IfModule mod_rewrite.c>

    RewriteEngine On
    AddDefaultCharset UTF-8

    ### Redirect regular PW JPEGs and PNGs to their WEBP image copies,
    ### if available and if the Browser supports WEBP:

        ## Does Browser accept WEBP images?
        RewriteCond %{HTTP_ACCEPT} image/webp

        ## Is it an existing file?
        RewriteCond %{REQUEST_FILENAME} -f

        ## Does a WEBP copy exist for it?
        RewriteCond %{DOCUMENT_ROOT}/$1$2$3/$4.webp -f

        ## With an added GET var or GET value of skiprewrite we do send the original JPEG or PNG
        RewriteCond expr "! %{QUERY_STRING} -strmatch '*skiprewrite*'"
        ## With an added GET var or GET value from the PW Page Editor, we do send the original JPEG or PNG
        RewriteCond expr "! %{QUERY_STRING} -strmatch 'nc=*'"

    ## Is it a regular PW JPEG or PNG image, stored under site/assets/files?
    RewriteRule ^(.*?)(site/assets/files/)([0-9]+)/(.*)\.(jpe?g|png)(.*)$  /$1$2$3/$4.webp [L]


	## Test that should show the original jpeg or png
    ###RewriteRule ^(.*?)(site/assets/files/)([0-9]+)/(.*)\.(jpe?g|png)$  /$1$2$3/$4.$5 [L]
  
	## Test with a PHP file in web root, that shows the references builded by the conditions. Useful for debugging with a direct call to a image url.
    ###RewriteRule ^(.*?)(site/assets/files/)([0-9]+)/(.*)\.(jpe?g|png)$  /matched.php?1=$1&2=$2&3=$3&4=$4&5=$5  [L]

</IfModule>

 

My matched.php for debugging:

Spoiler

<?php namespace ProcessWire;

echo "<ol>";
foreach($_GET as $item) echo "<li>{$item}</li>";
echo "</ol>";

$fn = $_SERVER['DOCUMENT_ROOT'] . '/' . $_GET[1] . $_GET[2] . $_GET[3] . '/' . $_GET[4] . '.webp';

echo "<p>{$fn} :: " . (file_exists($fn) ? 'yes' : 'no') . "</p>";

 

 

Examples in Opera with opened Network-Tab, requesting one image that has a webp copy, and requesting the second image that do not have a webp copy:

pw_htaccess_webp_support.thumb.gif.7791ff59d467fc7ee3dfaf0ea9aaf2d7.gif

Same page in Opera and old IE11:

pw_htaccess_webp_support.png.d110db833030e6825bb9c426f6bbcf0b.png

 

If we have a wider test case, the chance that this can be embedded into the PW .htaccess file for optional usage (commented by default) would be helpful for many users to support webp with less effort on their sites!

 

  • Like 3

Share this post


Link to post
Share on other sites
11 hours ago, horst said:

Please can someone test the .htaccess solution for WebP support in other environments?

It's working here in Laragon, Windows.

But won't this have the effect that if a visitor saves the image from their browser they will be saving a WEBP image with a JPG (PNG, GIF, etc) file extension? Might cause some confusion.

  • Like 2

Share this post


Link to post
Share on other sites

Thanks for your effort on this. I'll check it out this week and let you know my test findings.

  • Like 1

Share this post


Link to post
Share on other sites
On 4/28/2019 at 7:44 AM, Robin S said:

But won't this have the effect that if a visitor saves the image from their browser they will be saving a WEBP image with a JPG (PNG, GIF, etc) file extension? Might cause some confusion.

Thanks for testing. And yes, this is right.

But for me personally, (and for most of my clients), the main goal is to present pages with text and images on the screen, and not to let the visitors save images for later use. I think, if a visitor need a visual copy of a page, he still can save the complete page with his browser, or he can do screenshots. On photographer sites, the use of images independend from viewing the site / page are often prohibited. There it even should not be recognized that images with filetype jpeg in real are weppys. But that is my personal opinion, and maybe thats not a sufficient reason to include this into the PW htaccess.

But it also could be done the other way round: send .webp in markup and let the htaccess directives change this to (png|jpg) if a) the browser doesn't support this, or b) if there is no webp file available. This way round, in a 100% perfect site, all newer browsers would get 100% webp with correct file type. Only older browsers would get jpegs or pngs with file type webp. 🙂

  • Like 6

Share this post


Link to post
Share on other sites
5 hours ago, horst said:

I think, if a visitor need a visual copy of a page, he still can save the complete page with his browser, or he can do screenshots.

Because of this, is it worth also confusing the maintainers of the site? When debugging issues, it is easy to trip over files named in misleading ways.

  • Like 2

Share this post


Link to post
Share on other sites
3 hours ago, szabesz said:

When debugging issues,

you may use the new debug info for images.

and / or skip the rewrite: /site/assets/files/1/basename.jpg?skiprewrite 

On 4/27/2019 at 8:37 PM, horst said:

## With an added GET var or GET value of skiprewrite we do send the original JPEG or PNG
RewriteCond expr "! %{QUERY_STRING} -strmatch '*skiprewrite*'"

And: nobody is forced to use it this way. You always can create conditional markup. My goal is to collect different solutions, and with the .htaccess only, to show and discuss a solution that would not need a rewrite for existing sites, or at least, makes the rewrite as small as possible. (change all image variations in markup from .jpg to .webp).

EDIT:

3 hours ago, szabesz said:

confusing the maintainers

I think maintainers should know about the fact if they have implemented a webp solution and if so, wich one. If, for what ever reason, someone don't like this solution in a site, he shouldn't use it.

  • Like 3

Share this post


Link to post
Share on other sites

Hi @horst,
My ImageSizerEngineVips is based on your ImageSizerEngineIMagickCLI with code from other sizers. The module works fine, but at the moment only for my needs, because I optimized for speed and left some options like sharpening. But if I have the time and interest, I can polish it.
Another thing:
I only use WebP in pages with lazy loading and srcset. Because of that I have only variations as WebP, not the uploaded pageimage. Your change here checks not only variations, right? For me, it changes many variations that already exist. 

  • Like 1

Share this post


Link to post
Share on other sites

Hi Horst, I'm late on that one, thx for all your work! 🙂 

$image = $page->images->first()->size(300, 300);

?>
<picture>
    <?php if($image->hasWebp) { ?>
    <source srcset="<?=$image->srcWebp?>" type="image/webp" />
    <?php } ?>
    <source srcset="<?=$image->src?>" type="image/jpeg" />
    <img src="<?=$image->url?>" alt="Alt Text!" />
</picture>

What about something like this to ?

$image = $page->images->first()->size(300, 300);
echo $image->hasWebp(
  "<source srcset='{srcWebp}' type='image/webp'/>",
  "<source srcset='{src}' type='image/jpeg'/><img src='{url}' alt='{description}'/>"
);

Such a method could even be extended with custom templates set via $config->webp or the like and could also get a third argument for options. Then the example above could be:

echo $page->images->first()->size(300, 300)->hasWebp();

...and produce the exact same output as your example. Maybe $img->webp(...) would be a better name for such a method than $img->hasWebp(...)

Share this post


Link to post
Share on other sites
On 4/29/2019 at 9:38 PM, Noboru said:

I only use WebP in pages with lazy loading and srcset. Because of that I have only variations as WebP, not the uploaded pageimage. Your change here checks not only variations, right? For me, it changes many variations that already exist. 

@Noboru I now have changed it to work with all regular use cases in PW. But this includes to have a regular file and optionally a webp file. But this is/was the behave before the core webp addition too.

Please try if it now works for you, or report back. If not, we can define a custom hook or a custom function to suite your setup.

  • Like 2

Share this post


Link to post
Share on other sites

If you have mod_pagespeed on your server it can convert jpg to webp on the fly. Can do lots of other amazing stuff also.

  • Like 1

Share this post


Link to post
Share on other sites

This is great work here in this thread tho, awesome stuff.

  • Like 1

Share this post


Link to post
Share on other sites

Hello @horst,

thank you for your efforts to bring WebP to ProcessWire.

I can't wait till it is implemented in the core and want to try it out, but have some problems getting it to work. I hope you can help me:

I have downloaded your modified ProcessWire from your pull request and replaced the wire folder with your wire folder, because I don't want to mess up the Git development branch of my project. Maybe I don't understand the concept of pull requests right. 😀

Following files have changed:

  • wire/config.php
  • wire/core/ImageSizerEngine.php
  • wire/core/ImageSizerEngineGD.php
  • wire/core/Pageimage.php
  • wire/modules/Image/ImageSizerEngineIMagick/ImageSizerEngineIMagick.module

Now if I have understood correctly, I should be able to generate a WebP of an image with:

<?php

$options = [
	"webpAdd" => true,
	"webpQuality"=> 90
];

page()->image->size(800, 600, $options);

Now I get the error:

image.png.a580d1a56e219be19b70d247563286a9.png

Am I missing something or has it to do with my local MAMP?

Regards, Andreas

Share this post


Link to post
Share on other sites

Hi Andreas,

my first idea is that your local IMagick installation lacks webp support. Can you check this in phpinfo().

Opera_Momentaufnahme_2019-05-03_105059_kawobi.local.png.13ace311687d29995330d169d572393e.png

Share this post


Link to post
Share on other sites

Thank you for the hint, that seems to be it. Here is a screenshot of my local ImageMagick installed with Homebrew on MacOS:

image.png.ee146d3e6dd774c575def84476fb8d5a.png

But even when I uninstall the core module IMagick Image Sizer, I cannot create a WebP image with ImageSizerEngineGD.

Our hoster doesn't seem to support WebP either unfortunately.

Not so easy to use WepP at the moment. 😀

  • Sad 1

Share this post


Link to post
Share on other sites

@AndZyk I have sent a new commit to github to cover this. Please can you download the 3 new files:

core/Pageimage.php
core/ImageSizerEngineGD.php
modules/Image/ImageSizerEngineIMagick.module

If you want to test / debug the webp functionality of both engines in one call, please use code like this in a template file:

    $options = [
        'forceEngine' => 'ImageSizerEngineGD',
        'suffix' => 'gd',
        'forceNew' => true,
        'webpAdd' => true,
        'webpQuality' => 90,
        ];
    $img = $page->images->first->size(150, 150, $options);
	echo $img->getDebugInfo();

    $options = [
        'forceEngine' => 'ImageSizerEngineIMagick',
        'suffix' => 'im',
        'forceNew' => true,
        'webpAdd' => true,
        'webpQuality' => 90,
        ];
    $img = $page->images->first->size(150, 150, $options);
	echo $img->getDebugInfo();

A) it now should run without errors when you request a webp copy and the engine doesn't support it, and B) you can see it in the debug info if the selected engine supports webp.

engine-webp-supported.png.851f511528c85eeeac2cd50668695ad5.png

  • Like 1

Share this post


Link to post
Share on other sites

Thank you, I have downloaded your new commit and now I don't get an error anymore.

Unfortunately it seems, that the GD library and Imagick by MAMP doesn't support WebP yet. I found an tutorial how to recompile PHP for MAMP with WebP, but I rather wait for an update.

I noticed that the forceEngine option doesn't change the engine for me. I first had to uninstall the core module IMagick Image Sizer, so that the GD library would be used. Could that be a bug or have I done something wrong? 

It seems, that for now I will have to wait for more WebP support by MAMP and my hoster. But at least ProcessWire will be ready. 😉

Share this post


Link to post
Share on other sites
53 minutes ago, AndZyk said:

I noticed that the forceEngine option doesn't change the engine for me. 

Hmm, but it should. What priority settings do you have set?

Share this post


Link to post
Share on other sites

IMagick Image Sizer has priority 1. I think that is the default value.

Share this post


Link to post
Share on other sites

Yes, its the default. Weird!

Share this post


Link to post
Share on other sites

Hi @AndZyk,

you could try this:
brew install imagemagick
brew install pkg-config
pecl install imagick

For me this installs 
/Applications/MAMP/bin/php/php7.1.22/lib/php/extensions/no-debug-non-zts-20160303/imagick.so

In MAMP I switched to PHP 7.1.22 and edited in corresponding php.ini
MAMP_Imagick_MAMPextension=/Applications/MAMP/bin/php/php7.1.22/lib/php/extensions/no-debug-non-zts-20160303/imagick.so
 

Now MAMP should use a newer Imagmagick with WebP-Support.

Hope that helps.

Gruß
Armin

phpinfo().png

  • Like 2

Share this post


Link to post
Share on other sites
On 4/28/2019 at 7:44 AM, Robin S said:

But won't this have the effect that if a visitor saves the image from their browser they will be saving a WEBP image with a JPG (PNG, GIF, etc) file extension? Might cause some confusion.

This is the only disadvantage I see, but it might outweigh all the advantages.

On 4/29/2019 at 8:18 AM, arjen said:

Thanks for your effort on this. I'll check it out this week and let you know my test findings.

It works fine on my local docker environment. Nice 👍 I am moving servers, but I will check it out on a VPS but I won't see why it shouldn't work.

  • Thanks 1

Share this post


Link to post
Share on other sites

Thank you @Noboru, I will try this out. 😉

I am wondering: Can you even open WebP files in apps other than browsers without having the codec installed?

As far as I know you cannot simply open a .webp file. After all it is meant for browers. But I haven't tried it much.

In my opinion I would not serve WebP content in a .jpg or .png file. I would serve only WebP in a .webp file for browsers that support it. 😀

  • Like 2

Share this post


Link to post
Share on other sites

My favourite atm is to serve webp format in webp files and use the htaccess solution to detect missing browser support and then, as fallback, serve jpeg format in webp files. This false file types automatically will go away by time, as browser support becomes complete.

Edited by horst
  • Like 1

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    No registered users viewing this page.

  • Similar Content

    • By Peter Knight
      Is anyone here using WEBP as their output image format and what is your server / environment setup?
       I know there's support for it in PW lately and decided to investigate.
      Found it quite difficult to do this on a practical level. IE My current VPS is Cent OS 6 and Plesk and unless I'm wrong, WEBP is not supported by either.
      Which host and setup are you on that allows you to run WebP?
      Cheers
    • By Robin S
      Add Image URLs
      Allows images/files to be added to Image/File fields by pasting URLs.

      Usage
      Install the Add Image URLs module.
      A "Paste URLs" button will be added to all image and file fields. Use the button to show a textarea where URLs may be pasted, one per line. Images/files are added when the page is saved.
       
      https://github.com/Toutouwai/AddImageUrls
      https://modules.processwire.com/modules/add-image-urls/
    • By gebeer
      Hello all,
      sharing my new module FieldtypeImageReference. It provides a configurable input field for choosing any type of image from selectable sources. Sources can be: 
      a predefined folder in site/templates/ and/or a  page (and optionally its children) and/or the page being edited and/or any page on the site CAUTION: this module is under development and not quite yet in a production-ready state. So please test it carefully.
      UPDATE: the new version v2.0.0 introduces a breaking change due to renaming the module. If you have an older version already installed, you need to uninstall it and install the latest master version.
      Module and full description can be found on github https://github.com/gebeer/FieldtypeImageReference
      Install from URL: https://github.com/gebeer/FieldtypeImageReference/archive/master.zip
      Read on for features and use cases.
      Features
      Images can be loaded from a folder inside site/templates/ or site/assets Images in that folder can be uploaded and deleted from within the inputfield Images can be loaded from other pages defined in the field settings Images can be organized into categories. Child pages of the main 'image source page' serve as categories mages can be loaded from any page on the site From the API side, images can be manipulated like native ProcessWire images (resizing, cropping etc.), even the images from a folder Image thumbnails are loaded into inputfield by ajax on demand Source images on other pages can be edited from within this field. Markup of SVG images can be rendered inline with `echo $image->svgcontent` Image names are fully searchable through the API $pages->find('fieldname.filename=xyz.png'); $pages->find('fieldname.filename%=xy.png'); Accidental image deletion is prevented. When you want to delete an image from one of the pages that hold your site-wide images, the module searches all pages that use that image. If any page contains a reference to the image you are trying to delete, deletion will be prevented. You will get an error message with links to help you edit those pages and remove references there before you can finally delete the image. This field type can be used with marcrura's Settings Factory module to store images on settings pages, which was not possible with other image field types When to use ?
      If you want to let editors choose an image from a set of images that is being used site-wide. Ideal for images that are being re-used across the site (e.g. icons, but not limited to that).
      Other than the native ProcessWire images field, the images here are not stored per page. Only references to images that live on other pages or inside a folder are stored. This has several advantages:
      one central place to organize images when images change, you only have to update them in one place. All references will be updated, too. (Provided the name of the image that has changed stays the same) Installation and setup instructions can be found on github.
      Here's how the input field looks like in the page editor:

      If you like to give it a try, I'm happy to hear your comments or suggestions for improvement. Install from URL: https://github.com/gebeer/FieldtypeImageReference/archive/master.zip
      Eventually this will go in the module directory, too. But it needs some more testing before I submit it. So I'd really appreciate your assistance.
      Thanks to all who contributed their feedback and suggestions which made this module what it is now.
       
    • By rushy
      Hi. I've been using Processwire for a few years now and installed it on a few different shared hosting servers without issues, but I'm now running into an issue on a Fasthosts shared server that I've not seen before. The installation goes ok and I have a working default site profile but I am unable to complete any uploads of images. It just hangs at the progress spinner during the upload. I thought it might be a priviledge issue so have temporarily set the dir / file privs. as 777 / 666 just to test that but it made no difference. I have no errors in the wire log. In server error log I have:
      set_time_limit() has been disabled for security reasons in ....htdocs/wire/core/ImageSizerEngine.php on line 1035 and i note in the assets/file dir. where the image is being stored the date on the file being created has a year of 1970 and 0 length. If I leave the page this file disappears and nothing has been stored. 
      Does anyone know how I can enable set_time_limit if this is likely to be the problem? 
      Many thanks! Paul
    • By gebeer
      EDIT: all development and discussion of this module has been moved to Module FieldtypeImagePicker which now contains all features of this module and more. This module will not be maintained any further. The information below remains for pure historical reasons.
      I am happy to present my new fieldtype FieldtypeImageFromPage. It is made up of 2 modules:
      Fieldtype Image Reference From Another Page is a Fieldtype that stores a reference to a single image from another page. The image can be selected with the associated Inputfield.
      Inputfield Select Image From Page is an Inputfield to select a single image from images on a predefined page and it's children.
      And there also is a helper module that takes care of cleanup tasks.
      This module evolved out of a discussion about my other Module FieldtypeImagePicker.  It caters for use cases where a set of images is being reused multiple times across a site. With this fieldtype these images can be administered through a chosen page. All images uploaded to that page will be available in the inputfield.
      When to use ?
      Let editors choose an image from a set of images that is being used site-wide. Ideal for images that are being re-used across the site.
      Suited for images that are used on multiple pages throughout the site (e.g. icons).
      Other than the native ProcessWire images field, the images here are not stored per page. Only references to images on another page are stored. This has several advantages:
      one central place to organize images when images change, you only have to update them in one place. All references will be updated, too. (Provided the name of the image that has changed stays the same) Features
      Images can be manipulated like native ProcessWire images (resizing, cropping etc.) Image names are fully searchable through the API Accidental image deletion is prevented. When you want to delete an image from one of the pages that hold your site-wide images, the module searches all pages that use that image. If any page contains a reference to the image you are trying to delete, deletion will be prevented. You will get an error message to help you edit those pages and remove references there before you can finally delete the image. How to install and setup
      Download and install this module like any other modules in ProcessWire Create a page in the page tree that will hold your images. This page's template must have an images field Upload some images to the page you created in step 2 Create a new field. As type choose 'Image Reference From Another Page'. Save the field. In 'Details' Tab of the field choose the page you created in step 2 Click Save button Choose the images field name for the field that holds your images (on page template from step 2) Click Save button again Choose whether you want to include child pages of page from step 2 to supply images Add the field to any template You are now ready to use the field View of the inputfield on the page edit screen:

      View of the field settings

      The module can be installed from this github repo. Some more info in the README there, too.
      In my tests it was fairly stable. After receiving your valued feedback, I will eventually add it to the modules directory.
      My ideas for further improvement:
      - add ajax loading of thumbnails
      Happy to hear your feedback!
       
×
×
  • Create New...