skip to Main Content

I need to convert an image (png) to (webp) file.

After uploading a png file, the webp image has been generated, but the webp file didn’t copy the transparency of a png file, instead it creates a black background.

This is my php code:

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

The version of PHP is 5.6

4

Answers


  1. You may have to enable the alpha channel and save it. Maybe try this:

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

    The version of PHP is 5.6

    Login or Signup to reply.
  2. Tested on 7.3.0 — works.

    DISCLAIMER: May only work on later or some PHP versions.

    Only tested on 5.6.15 (didn’t work, black background) and 7.3.0 (worked, transparent background).

    Here’s the code:

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

    Edit 1. *** PROOF

    The PHP GD library relies on the libgd library.

    Link:

    https://github.com/libgd/libgd

    Relevant code on saves (file: gd_webp.c), Excerpt showing respect of Alpha channel when present:

                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;
    

    In regards to static int _gdImageWebpCtx (gdImagePtr im, gdIOCtx * outfile, int quality)

    The PHP code I presented relies on the fact that alpha is indeed respected in the GD library and as such works if tested in later PHP version than you are using, specifically I tested in 7.3.0 but may work in early releases after your version.

    Login or Signup to reply.
  3. just add :

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

    between $im = imagecreatefrompng($file); and 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);
    

    put the image somewhere like:

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

    and you should see your webp in the proper way

    Login or Signup to reply.
  4. There is no need to copy the source image, if the output format supports full alpha transparency. Instead, it is sufficient to tell GD to preserve the alpha channel when saving:

    $im = imagecreatefrompng($infilename);
    imagesavealpha($im, true);
    imagewebp($im, $outfilename);
    
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search