6

Recently I've been fiddling with the WebP image format. I use php 5.5.12 for this, with the gd library installed (gd 2.1.0 / webp supported). I noticed that for some reason, PHP creates corrupted webp-images. The code I used is the following:

$im= imagecreatefromjpeg("test_img.jpg");
$succes = imagewebp($im, "test_img.webp");
if ($im !== false && $succes == true) {
    echo "Succes.";
}

I fail to grasp why the webp image written to the filesystem by this php script is corrupt. For your convenience, I have attached one of the test images. After processing, its associated webp image is indeed a corrupt image on my system. I'd appreciate your input on this, as I have no idea why this does not work properly.

Image: https://i.stack.imgur.com/pwZHv.jpg (JPEG)

Nelewout
  • 6,281
  • 3
  • 29
  • 39

3 Answers3

15

Some versions of libgd forget to add a zero padding at the end of odd-sized webp files (this bug, as already mentioned).

It can be fixed with PHP. Replace this:

imagewebp($im);

With this:

ob_start();
imagewebp($im);
if (ob_get_length() % 2 == 1) {
    echo "\0";
}
ob_end_flush();

Or alternatively, if you want to create a file rather than output the result directly:

imagewebp($im, 'test_img.webp');
if (filesize('test_img.webp') % 2 == 1) {
    file_put_contents('test_img.webp', "\0", FILE_APPEND);
}
Alex Pérard
  • 151
  • 1
  • 5
  • Does this fix applies to when I convert files to webp the output is just blank, it's not a broken image but a blank transparent image. – Jed Jun 02 '16 at 08:15
  • I have also experienced a transparent image, but with correct dimensions, even though I have applied the patch. I'm very interested in learning under which circumstances this happens. It will be used for a PHP library for converting webp images using multiple methods. GitHub page: https://github.com/rosell-dk/webp-convert – rosell.dk Jun 22 '17 at 09:57
  • 1
    Someone experienced that the webp was odd sized with the version you posted where a file is created. I guess this means that the `file_put_contents` failed. Could it be that it is a problem to write to the same file so quickly after the first write? It cannot be permission problems, can it, since the file was created alright. The issue was reported here: (https://wordpress.org/support/topic/images-not-seen-on-chrome/#post-11390284) – rosell.dk Apr 04 '19 at 08:41
3

For those of you running into the same problems as I did, here is a link to an (at this time) open PHP bugtracker that is - to my knowledge - the source of the problem. https://bugs.php.net/bug.php?id=66590

It is sad indeed that this is still not fixed, but we can solve it rather elegantly ourselves. For each VP8 frame written by imagewebp(), we need to check if the frame length is even. If this is not the case, we append a zero byte to the end of the frame and continue. Updating of the frame length defined in its header is not relevant, since this is already of proper length - the padding necessary was just never properly added to the file itself.

Nelewout
  • 6,281
  • 3
  • 29
  • 39
0

May I propose ImageMagick as an alternative?

   $im = new Imagick('image.jpg');
   $im->writeImage('image.webp');
Mark Setchell
  • 191,897
  • 31
  • 273
  • 432
  • This would only work when ImageMagick _has access to the webp library_. If this is the case, ImageMagick is a great library to use. If not, you'll have to use a work-around. You'd run into PHP errors on `$im->writeImage('image.webp');`. – Nelewout Oct 05 '15 at 09:03