imagewebp(php)创建损坏的webp文件

时间:2022-05-07 21:20:06

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:

最近我一直在摆弄WebP图像格式。我使用php 5.5.12,安装了gd库(支持gd 2.1.0 / webp)。我注意到由于某种原因,PHP会创建损坏的webp图像。我使用的代码如下:

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

我无法理解为什么这个php脚本写入文件系统的webp图像已损坏。为方便起见,我附上了一张测试图片。处理后,其关联的webp图像确实是我系统上的损坏图像。我很感激你对此的意见,因为我不知道为什么这不能正常工作。

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

图片:http://i.stack.imgur.com/pwZHv.jpg(JPEG)

3 个解决方案

#1


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

某些版本的libgd忘记在奇数大小的webp文件的末尾添加零填充(这个bug,如前所述)。

It can be fixed with PHP. Replace this:

它可以用PHP修复。替换这个:

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);
}

#2


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

对于那些遇到与我一样的问题的人来说,这里是一个链接到(此时)开放的PHP bugtracker,据我所知,这是问题的根源。 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.

确实令人遗憾的是,这仍然没有固定,但我们可以自己相当优雅地解决它。对于imagewebp()编写的每个VP8帧,我们需要检查帧长度是否均匀。如果不是这种情况,我们将一个零字节附加到帧的末尾并继续。更新其标头中定义的帧长度是不相关的,因为它已经具有适当的长度 - 所需的填充从未正确添加到文件本身。

#3


May I propose ImageMagick as an alternative?

我可以提议将ImageMagick作为替代方案吗?

   $im = new Imagick('image.jpg');
   $im->writeImage('image.webp');

#1


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

某些版本的libgd忘记在奇数大小的webp文件的末尾添加零填充(这个bug,如前所述)。

It can be fixed with PHP. Replace this:

它可以用PHP修复。替换这个:

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);
}

#2


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

对于那些遇到与我一样的问题的人来说,这里是一个链接到(此时)开放的PHP bugtracker,据我所知,这是问题的根源。 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.

确实令人遗憾的是,这仍然没有固定,但我们可以自己相当优雅地解决它。对于imagewebp()编写的每个VP8帧,我们需要检查帧长度是否均匀。如果不是这种情况,我们将一个零字节附加到帧的末尾并继续。更新其标头中定义的帧长度是不相关的,因为它已经具有适当的长度 - 所需的填充从未正确添加到文件本身。

#3


May I propose ImageMagick as an alternative?

我可以提议将ImageMagick作为替代方案吗?

   $im = new Imagick('image.jpg');
   $im->writeImage('image.webp');