查看你系统中的 imagemagick是否支持 webp

convert -version


Version: ImageMagick 6.8.9-9 Q16 x86_64 2018-07-10 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2014 ImageMagick Studio LLC
Features: DPC Modules OpenMP
Delegates: bzlib cairo djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png rsvg tiff wmf x xml zlib



卸载已经安装的 imagemagick

sudo apt-get remove imagemagick
sudo apt-get autoremove imagemagick

先安装依赖包:libwep 再重新安装 imagemagick

apt-get install libjpeg-dev libpng-dev libtiff-dev libgif-dev libwebp-dev devscripts

下载最新版 imagemagick 编译安装 或 apt 重装安装

php 5.x 使用 6.9版本 http://www.imagemagick.org/download/ImageMagick-6.9.10-8.tar.gz


cd /tmp
wget http://www.imagemagick.org/download/ImageMagick.tar.gz
tar -xvf ImageMagick.tar.gz
cd ImageMagick-7.0.*
./configure --prefix=/usr
sudo make install
sudo ldconfig /usr/local/lib


convert -version
Version: ImageMagick 7.0.8-8 Q16 x86_64 2018-08-04 https://www.imagemagick.org
Copyright: © 1999-2018 ImageMagick Studio LLC
License: https://www.imagemagick.org/script/license.php
Features: Cipher DPC HDRI OpenMP
Delegates (built-in): bzlib djvu fontconfig freetype gvc jbig jng jpeg lcms lqr lzma openexr png tiff webp wmf x xml zlib

有了 webp 的信息



WebP Support with ImageMagick and PHP

I've been wanting to get WebP set-up on my site for a little while now, the biggest barrier to entry has been getting it integrated into the flow already had, where I generate different sized images where I need to.

It turns out you can use ImageMagick if it can find libwebp-dev when it's built.

By default, unfortunately, Ubuntu doesn't come with ImageMagick built with WebP support and I'm assuming the same is true for Debian (I got everything working on Ubuntu and went through the same process on Debian - didn't check Debian needed this, I just assumed).

Anyway, I stumbled on this post which outlines how you can build webp support into ImageMagick.


Check Your Version

After landing WebP I ended up hitting a problem later on where the alpha channel was messed up somewhere in the WebP conversion and displayed a black background - Booooo.

Turns out this is a bug in ImageMagick.

The way to get around the problem is to install a version higher than or equal to 6.8.3-0 Beta. This may be an option for you using the information on this ImageMagick post. The problem here, is that to compile newer versions of ImageMagick you need to have version 0.3.0 or higher of libwebp. Debian (and possibly) Ubuntu ships with 0.1.3. You can check yours with:

sudo aptitude versions libwebp-dev

What to do? Well I bailed at this point. The code is sat on my server, but disabled by a boolean. When I get a newer version of ImageMagick or libwebp I will update everything and see if enabling it works or not.

Adding WebP Support to ImageMagick

To support WebP conversion in ImageMagick I had to install libwebp-dev with:

sudo apt-get install libwebp-dev

Then it was a case of rebuilding ImageMagick.

cd /tmp
mkdir imagemagick
cd imagemagick
sudo apt-get build-dep imagemagick
sudo apt-get install libwebp-dev devscripts
sudo apt-get install graphicsmagick-imagemagick-compat
apt-get source imagemagick
cd imagemagick-*
debuild -uc -us
sudo dpkg -i ../*magick*.deb

This all seemed to work, although I did get some weird/scary looking error messages after the final command.

Errors were encountered while processing:

What I ended up doing to get around this was run the following:

sudo apt-get -f install
sudo dpkg -i ../imagemagick_6.7.7.10-5+deb7u3_amd64.deb

Web Page Test

I ran everything through WebPageTest.org and WebP has a positive impact on my site (surprise, surprise).

On the home page the image went from 141.5 KB to 66.8 KB and that results in a load time from 959 ms to 393 ms.

You can see the difference in the results below.

WebPageTest Results Before WebP

WebPageTest Results After WebP

How Do You Convert to WebP?

One thing I do on my site is format the file names in the URL in such a way that it includes the desired image dimensions as well as the density of the screen.

This means I can decide what size image I send to the browser.

For that reason, I got ImageMagick to do a couple of extra things, other than just convert, it strips the images metadata, crops it and then resizes it.

function resizeAndConvertImageWebP(
        $resizedFilepath) {
    $newWidth = $width * $density;
    $newHeight = $height * $density;

    $image = new Imagick($originalFilepath);
    $origImageDimens = $image->getImageGeometry(); 
    $origImgWidth = $origImageDimens['width']; 
    $origImgHeight = $origImageDimens['height']; 

    if($newWidth == 0) {
        $ratioOfHeight = $newHeight / $origImgHeight;
        $newWidth = $origImgWidth * $ratioOfHeight;

    if($newHeight == 0) {
        $ratioOfWidth = $newWidth / $origImgWidth;
        $newHeight = $origImgHeight * $ratioOfWidth;

    $widthRatios = $origImgWidth / $newWidth;
    $heightRatios = $origImgHeight / $newHeight;

    if($widthRatios <= $heightRatios) {
        $cropWidth = $origImgWidth;
        $cropHeight = $newWidth * $widthRatios;
    } else {
        $cropWidth = $newHeight * $heightRatios;
        $cropHeight = $origImgHeight;

    $cropX = ($origImgWidth - $cropWidth) / 2;
    $cropY = ($origImgHeight - $cropHeight) / 2;

    $image->cropImage($cropWidth, $cropHeight, $cropX, $cropY);
    $image->resizeImage($newWidth, $newHeight, imagick::FILTER_LANCZOS, 0.9);
    $image->setBackgroundColor(new ImagickPixel('transparent'));

The important lines of code for WebP conversion are:

$image->setBackgroundColor(new ImagickPixel('transparent'));

This defines the final image format to WebP and then ensures that if you are converting a PNG, it keeps any alpha channels.

Apache GD Method for WebP Conversion

The Apache GD library can actually handle WebP as well and this was going to be my original approach, however some issues in the library caused it to incorrectly pad the file so it fails to render.

More info here: https://bugs.php.net/bug.php?id=66590

If that wasn't an issue, the basic code would look something like:

$im = $this->imageCreateFromAny($originalFilepath);
if(!$im) {
    // Unrecognized format
    return false;

imagewebp($im, $resizedFilepath);

Where imageCreateFromAny is a method I found from this PHP Doc.

function imageCreateFromAny($filepath) { 
    $type = exif_imagetype($filepath); // [] if you don't have exif you could use getImageSize() 
    $allowedTypes = array( 
        1,  // [] gif 
        2,  // [] jpg 
        3,  // [] png 
        6   // [] bmp 
    if (!in_array($type, $allowedTypes)) { 
        return false; 
    switch ($type) { 
        case 1 : 
            $im = imageCreateFromGif($filepath); 
        case 2 : 
            $im = imageCreateFromJpeg($filepath); 
        case 3 : 
            $im = imageCreateFromPng($filepath); 
        case 6 : 
            $im = imageCreateFromBmp($filepath); 
    return $im;  

Detecting WebP Support or Not

Browsers which support WebP will include an accept header for 'image/webp' which I just look for and take that as a go ahead to serve up WebP.

// Do we support WebP?
$webpsupport = (strpos($_SERVER['HTTP_ACCEPT'], 'image/webp') >= 0);
if($webpsupport) {
    $this->attemptToServeWebP($pathinfo, $matches, $width, $height, $density);
} else {
    $this->attemptToServeNormal($pathinfo, $matches, $width, $height, $density);

Useful Tid-Bit

If you need to delete all of your auto generated WebP files for some reason, this will delete all of them from your current directory (including sub-directories).

sudo find . -type f -iname \*.webp -delete


WebP is pretty cool for shaving off some extra page weight and it's not too bad to support if you have some kind of image generation in place already.

If not, then it may be worth looking for a Grunt or Gulp task to do it.

Grunt has grunt-webp

Gulp has gulp-webp

Orig Photo: https://flic.kr/p/9UTtaf