如何将PNG文件转换为WebP文件

10

我需要将一张图片(png)转换成webp格式。

上传了一张png文件后,生成了一个webp图片,但是这个webp文件没有复制png文件的透明度,反而创建了一个黑色背景。

以下是我的php代码:

$type = wp_check_filetype($file, null);
$ext = $type['ext'];
if ($ext === 'png') {
    $im = imagecreatefrompng($file);
    imagepalettetotruecolor($im);
    $webp = imagewebp($im, str_replace('png', 'webp', $file));
}
imagedestroy($im);

PHP的版本是5.6


使用PHP Webp库。请参见此处 https://github.com/S1SYPHOS/php-webp/blob/master/README.md - Vaibhavi S.
请再次检查 https://github.com/S1SYPHOS/php-webp。 - Vaibhavi S.
谢谢,但是你有没有想过如何在不使用任何库的情况下解决这个问题? - Jordan Lipana
没有,我完全不知道如何在没有任何库的情况下实现这个。 - Vaibhavi S.
@JordanLipana 我有一个解决方案。但这取决于足够高的PHP版本。我很快会发布它。我首先在5.6上进行了测试 - 不行。然后在7.2(更正为7.3.0)上进行了测试 - 成功了。我将再次检查5.6上的更改,然后发布解决方案,并声明如果php版本有关。更新:解决方案已发布。 - GetSet
请注意,乔丹在我发布解决方案后添加了PHP 5.6位。也就是说,在我直接告诉他WebP的透明度在PHP 5.6中无法正常工作之后,他才添加了5.6作为要求。对我来说似乎有点不合逻辑,但嘿,我只是在这里围着地球转。 - GetSet
4个回答

12

测试通过7.3.0 -- 可用。

免责声明:可能仅适用于更高或某些PHP版本。

仅在5.6.15(未能正常工作,黑色背景)和7.3.0(可用,透明背景)上进行了测试。

以下是代码:

// get png in question

$pngimg = imagecreatefrompng($file);

// get dimens of image

$w = imagesx($pngimg);
$h = imagesy($pngimg);;

// create a canvas

$im = imagecreatetruecolor ($w, $h);
imageAlphaBlending($im, false);
imageSaveAlpha($im, true);

// By default, the canvas is black, so make it transparent

$trans = imagecolorallocatealpha($im, 0, 0, 0, 127);
imagefilledrectangle($im, 0, 0, $w - 1, $h - 1, $trans);

// copy png to canvas

imagecopy($im, $pngimg, 0, 0, 0, 0, $w, $h);

// lastly, save canvas as a webp

imagewebp($im, str_replace('png', 'webp', $file));

// done

imagedestroy($im);  

编辑1。*** 证明

PHP GD库依赖于libgd库。

链接:

https://github.com/libgd/libgd

有关saves的相关代码(文件:gd_webp.c),摘录显示Alpha通道存在时的尊重:

            c = im->tpixels[y][x];
            a = gdTrueColorGetAlpha(c);
            if (a == 127) {
                a = 0;
            } else {
                a = 255 - ((a << 1) + (a >> 6));
            }
            *(p++) = gdTrueColorGetRed(c);
            *(p++) = gdTrueColorGetGreen(c);
            *(p++) = gdTrueColorGetBlue(c);
            *(p++) = a;

关于static int _gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality)的问题,我呈现的PHP代码依赖于GD库确实尊重alpha,并且因此有效,如果在您正在使用的较早版本之后的版本中进行测试,则可以工作,特别是我在7.3.0中进行了测试。


1
@JordanLipana 我的解决方案从技术上解决了你的问题。然而,我们将看到这如何发挥作用。Jordan,GD库在5.6中不支持它。PHP 5.6中的GD版本不支持alpha模式。谷歌文档提供了3种模式。根据我的测试,PHP 5.6不使用alpha通道模式来处理webp。 - GetSet
听着,去年底我曾经使用GD库拼凑优惠券的最终图像,所以当我看到你的问题时,我就开始解决了。我检查了你的问题的C源代码,看看alpha是否被尊重:在最新版本中是这样的。我没有试图追踪PHP 5.6使用的内容。很有可能当时PHP不支持alpha,否则为什么到目前为止还没有人为那个版本提供解决方案呢? - GetSet
你好,你有没有关于PHP 5.6中的GD库不支持将png转换为webp的链接?我需要告诉我的团队。 - Jordan Lipana
你仍然可以将背景颜色设置为任何你想要的颜色。即使白色与你的页面或容器匹配,也可以选择它作为背景颜色。但是,如果你希望背景具有透明效果,在PHP 5.6中就无法实现,除非你替换它所使用的GD库。 - GetSet
@JordanLipana 如果这个对话陷入僵局,我会向管理员询问。 - GetSet
显示剩余7条评论

0

如果输出格式支持完全的 alpha 透明度,就没有必要复制源图像。相反,只需要告诉 GD 在保存时保留 alpha 通道即可:

$im = imagecreatefrompng($infilename);
imagesavealpha($im, true);
imagewebp($im, $outfilename);

0

您可能需要启用 alpha 通道并保存它。也许可以尝试这样做:

$ext = $type['ext'];
if ($ext === 'jpg' || $ext === 'jpeg') {
    $im = imagecreatefromjpeg($file);
    $webp = imagewebp($im, str_replace($ext, 'webp', $file), 70);
} elseif ($ext === 'png') {
    $im = imagecreatefrompng($file);
    imagepalettetotruecolor($im);

    imageAlphaBlending($im, true); // alpha channel
    imageSaveAlpha($im, true); // save alpha setting

    $webp = imagewebp($file, str_replace('png', 'webp', $file));
}
imagedestroy($im);

PHP的版本是5.6。

谢谢您的回复,但是这段代码并没有将PNG转换为WebP格式。我还修改了imagewebp($file, str_replace('png', 'webp', $file));,将其改为imagewebp($im, str_replace('png', 'webp', $file));,但结果仍然相同,即透明度被转换成黑色。 - Jordan Lipana
我有一个解决方案。但它取决于足够高的PHP版本。很快会发布。我首先在5.6上进行了测试 - 不行。然后在7.2上测试 - 成功了。将再次检查我的更改是否适用于5.6,然后发布解决方案,并声明如果php版本有影响。 - GetSet

-1

只需添加:

imagealphablending($im, true);
imagesavealpha($im, true);

在 $im = imagecreatefrompng($file); 和 imagewebp(.. 之间

$type = wp_check_filetype($file, null);
$ext = $type['ext'];
if ($ext === 'png') {
  $im = imagecreatefrompng($file);
  imagealphablending($im, true);
  imagesavealpha($im, true);
  $webp = imagewebp($im, str_replace('png', 'webp', $file));
}
imagedestroy($im);

将图像放在某个地方,例如:

<html>
  <body style="background-color:red;">
    <img src="url_of_your_img.webp">
  </body>
</html>

然后你应该以正确的方式看到你的webp


1
只需添加 imagealphablending($im, true); imagesavealpha($im, true);。这是一个误解。根据php.net的说明,必须选择其中之一:为了保留第一个alpha通道,必须禁用Alphablending(imagealphablending($im, false))。 来自 https://www.php.net/manual/en/function.imagesavealpha.php - GetSet

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接