Jump to content

Webp support


jacmaes

Recommended Posts

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
Link to comment
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
Link to comment
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
Link to comment
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
Link to comment
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
Link to comment
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 2
Link to comment
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(...)

Link to comment
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
Link to comment
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

Link to comment
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
Link to comment
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
Link to comment
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. ?

Link to comment
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?

Link to comment
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
Link to comment
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
Link to comment
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
Link to comment
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
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
×
×
  • Create New...