Jump to content

Webp support


jacmaes

Recommended Posts

One of PW 3.010's major novelty was the introduction of Horst's new image resizing engine that uses ImageMagick. Now I understand that ImageMagick can convert images to Webp, the image format that Google says can reduce image size up to 34% compared to JPEG.

Mozilla is apparently adding support to Firefox, and even the Safari team is playing with it, so it looks like Webp is soon going to be available in most major browsers. If Horst's module can be extended to add Webp conversion, that would be a great addition to PW's already very powerful image manipulation arsenal. 

I'm currently using the free ImageEngine Lite to serve Webp images to supporting browsers, and the results are impressive. I routinely get images that are between 25 and 60% smaller compared to JPEG, with the same visual quality. I would love to eliminate the need to rely on a third-party service though. 

  • Like 17
Link to comment
Share on other sites

  • 2 years later...

Is there any update on this, doesn't look like many of the browsers have followed the google team by implementing. Love to have a simply solution for converting to webp in PW too if that might be available, even if its for opera and chrome users. something like

image->size(1000,0,"webp");

or

webp = image->convert("webp")

 

Link to comment
Share on other sites

  • 3 weeks later...
  • 3 weeks later...

We need WebP support in the core as it only has advantages (and one disadvantage): Edge (yes, Edge) supports it, as well as Chrome, the Android Browser (since 4.2) and Opera. Firefox 65 which will be released in January 2019 will implement it very soon and the Safari team is also experimenting with it.

The disadvantage is, that images that are being downloaded can not be opened with standard OS applications, but with tools like IrfanView or XnView you can also view WebP files. This makes it also hard to share these images and is why Facebook removed WebP from their service, as people tend to download and share the images. But I think thats not the case for most websites. And also it is a decision of the developer, if he uses WebP or another image format. So we have no drawbacks if this would be in the core (or a module, but I don't see why it should be a module).

Link to comment
Share on other sites

Some thoughts / infos in no special order:

it has to be a module because all our image engines are modules. 

As long as the GD library does not support webp, it cannot be a core fileformat. 

I haven't tested anything in regard of webp til now. If imagick supports it as outputformat, I can start testing it as a image engine module that extends the core imagick module to provide something like a options variable to return the final variation image as webp. 

Earliest start can be around christmas time 2018. 

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

1 hour ago, horst said:

As long as the GD library does not support webp, it cannot be a core fileformat.

GD supports webp: http://php.net/manual/en/image.installation.php

Quote

To enable support for webp add --with-vpx-dir=DIR . Available as of PHP 5.5. As of PHP 7.0.0 --with-webp-dir=DIR has to be added, i.e. support for libvpx has been removed in favor of libwebp.

 

  • Like 2
Link to comment
Share on other sites

1 hour ago, Beluga said:

GD supports webp

Ah, a quick test showed that I can use this already with my local dev environment:

$cai3 = $page->croppable_images->first()->getCrop('thumb100');
// WebP with GD-lib bundled with PHP 7
$im = imagecreatefromjpeg($cai3->filename);
imagewebp($im, str_replace('.jpg', '.webp', $cai3->filename));
imagedestroy($im);

?

  • Like 5
Link to comment
Share on other sites

@horst Niiiice! I've just tried on a live server with PHP 7.2 installed. Your code works great. The Webp image is successfully generated from the original JPEG. Here's how I've echoed it:

 

		$main_image = $page->image->first->getCrop('grande'); // (using Horst's Croppable Image module in this example)
		$image = imagecreatefromjpeg($main_image->filename);
		imagewebp($image, str_replace('.jpg', '.webp', $main_image->filename));
		imagedestroy($image);
		$webp_image = str_replace('.jpg', '.webp', $main_image->url);
		echo "<img class='responsive-image' src='$webp_image' alt=''>";

 

Note: for those using the Plesk control panel, webp support for GD seems to be disabled by default.

  • Like 2
Link to comment
Share on other sites

Probably not news to anyone familiar with webp, but I just tried it and the reduction in file size is impressive indeed. WEBP image on the left generated from variation with 100% quality, JPG on the right with default PW quality setting. Interesting that there is a slight but perceptible difference in colour though.

2018-11-30_110000.jpg.b49940d9d841016dac1502d725c45561.jpg

  • Like 4
Link to comment
Share on other sites

@arjen the support via lazyload sounds very interesting. This way we only have to care that both fileformats are available on the server. There is no extra markup needed. Only downside is the missing noscript support. So the usefulness depends on the usecase. 

?

  • Like 2
Link to comment
Share on other sites

  • 3 weeks later...

Want to announce that I started with embedding support for the WebP format into the core.

Current state in my dev-branch is, that you can call / create additional image variations in the WebP format by passing this param within an options array to any size call:

// mandatory is: 'webpAdd' => true
// optionally define a quality for WebP: 'webpQuality' => 80
// currrently it only is implemented in the GD-Engine, so you need to force its use,

$options = [
    'forceEngine' => 'ImageSizerEngineGD',
    'forceNew' => true,
    'webpAdd' => true,
    'webpQuality' => 80
    ];
$image = $page->images->first->size(700, 700, $options);

 

If you want to be an early tester, you can get a fork from here (patch-1), or you grap these three files:

More will be done between christmas and new year!

 

screen-webp-start.thumb.jpg.20d914371b40284314569ff6746627fd.jpg

  • Like 4
  • Thanks 5
Link to comment
Share on other sites

Can we make the api a bit more flexible like:

$options = [
  'additionalFormats': ['webp'],
  'webp' => [
    'quality' => 80
  ]
];

This way we can easily add any other formats, which might emerge and have the possibility to not only have a single additional format generated. And as soon as we might generate multiple formats / images per sizing operation I feel like namespacing options like quality might prevent an explosion of possible root level options.

  • Like 2
Link to comment
Share on other sites

1 hour ago, LostKobrakai said:

Can we make the api a bit more flexible

I believe that this would need a huge rewriting of the complete images files (Pageimage and the SizerEngines). My first thought also was to enhance it to use different outputformats, as you can read above, (or maybe only in the github issues).

But with this first take, I definetly want to use only webp and only as a sidecar file. Other things, like selectable and multiple outputformats are not in the first line.

Thats because I have not that much time atm to start a huge rewrite, but want to have the compression advantage of webp integrated directly in PW, as this will be the first possibility included in the core, without usage of external tools and also without extra manipulation steps. And for that purpose, it seems to me enough to implement just another single param.

 

1 hour ago, LostKobrakai said:

This way we can easily add any other formats, which might emerge and have the possibility to not only have a single additional format generated

It will be definetly not "easily", as the imagesizer was and is designed to only resize and crop a single image. It is not an image manipulator. And the todo work not will be the ImageSizerEngines but the Pageimage.php, the tempfiles generation and how all this currently works together.

  • Like 1
Link to comment
Share on other sites

@horst As you wrote the webP will be generated in addition to the normal resized image, is that correct? 

How would I echo the different formats? Are there different URLs for the normal jpg image and another URL for the WebP image?

For example to use it in a picture element like I discribed in the Github issue

<picture>
  <source srcset="{$image->size(700,700,$options)->url('webp')}" type="image/webp">
  <source srcset="{$image->size(700,700,$options)->url}" type="image/jpeg"> 
  <img src="{$image->url}" alt="Alt Text!">
</picture>

 

Link to comment
Share on other sites

15 hours ago, horst said:

But with this first take, I definetly want to use only webp and only as a sidecar file.

That's totally fine. We could simply not support different formats besides webp for now. I was really just talking about the configuration, so if there is time in the future to have a more extensive featureset supported we don't need to change the configuration, but can just add the features / remove warnings.

  • Like 3
Link to comment
Share on other sites

8 hours ago, LostKobrakai said:

I was really just talking about the configuration, so if there is time in the future to have a more extensive featureset supported we don't need to change the configuration, but can just add the features / remove warnings.

That's the part that is bound to the Pageimage class. Maybe it could be takled by a little extra layer / function, that maps a new configuration API to the old cryptic one, as I do with PIA and her selector strings?

Link to comment
Share on other sites

15 hours ago, jmartsch said:

How would I echo the different formats?

With a hook in site/ready.php like this one,

// hook for pageimages to return a webp url
$wire->addHookProperty('Pageimage::urlWebp', function($event) {
    $image = $event->object;
    $path_parts = pathinfo($image->filename);
    $webpFilename = $path_parts['dirname'] . '/' . $path_parts['filename'] . '.webp';
    if(!is_readable($webpFilename)) {
        $event->return = '#';  // what should be returned for none existing webp variations ?
        return;
    }
    $path_parts = pathinfo($image->url);
    $webpUrl = $path_parts['dirname'] . '/' . $path_parts['filename'] . '.webp';
    $event->return = $webpUrl;
});

you can use it for testing purposes right now.

screen-webp-url-property.jpg.69c6dc0d25b51bc9bd6245632480a563.jpg

  • 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...