Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Warn users on older versions of Gd, that it looses the alpha channel #238

Closed
rosell-dk opened this issue Oct 23, 2019 · 7 comments
Closed
Assignees

Comments

@rosell-dk
Copy link
Owner

rosell-dk commented Oct 23, 2019

Old versions of Gd does not handle transparency (in some PNGs)
Experienced in GD Version: 2.1.1-dev.

Also discussed here: rosell-dk/webp-express#374

@rosell-dk rosell-dk self-assigned this Oct 23, 2019
@rosell-dk
Copy link
Owner Author

There is hope. Perhaps the solution is here or here.

@rosell-dk
Copy link
Owner Author

rosell-dk commented Oct 24, 2019

The following code demonstrates that old versions of Gd looses the alpha channel when saving WebP, but is able to retain it when saving PNG:
The version I see it fail on is: GD Version: 2.1.1-dev, PHP version: 5.5.9-1ubuntu4.29.

if (!extension_loaded('gd')) {
  echo 'Gd extension is not available. The test cannot be run.'; exit;
}
if (!function_exists('imagewebp')) {
    echo 'Gd has been compiled without webp support and the test cannot be run.'; exit;
}
if (!function_exists('imagecreatefrompng')) {
    echo 'Gd has been compiled without PNG support and the test cannot be run.'; exit;
};

echo 'PHP version: ' . PHP_VERSION . '<br>';
echo 'GD Version: ' . gd_info()["GD Version"] . '<br>';

// Create 50x50 true color
$new = imagecreatetruecolor(50, 50);
$color = imagecolorallocatealpha($new, 0, 0, 0, 70);
imagefill($new, 0, 0, $color);

// Set flag to retain full alpha channel when saving PNG
// Works for PNG, but seems to have no effect for saving WebP
if (imagesavealpha($new, true) === false) {
    echo 'imagesavealpha() failed!';
}

$destinationWebp = __DIR__ . '/test.webp';
imagewebp($new, $destinationWebp);
if (filesize($destinationWebp) % 2 == 1) {
    file_put_contents($destinationWebp, "\0", FILE_APPEND);
}

$destinationPng = __DIR__ . '/test.png';
imagepng($new, $destinationPng);

On newer Gd, both the PNG and the WebP are semitransparent. On older Gd, the WebP is completely black.

It seems that imagesavealpha() has no effect for webp - but only applies to png. It does not have any affect in newer Gd either (setting to false does not make it black). This is in accordance with the documentation, which says that it applies to PNG. There is no equivalent function for webp, so this flag cannot be controlled for webp. Older Gd versions simply discards alpha channel while newer versions simply retains it.

It would seem that all hope is lost for retaining alpha channel for webp on old Gd.

@rosell-dk
Copy link
Owner Author

Here is a link to knowledge on the PNG format. http://www.libpng.org/pub/png/book/chapter08.html

@rosell-dk
Copy link
Owner Author

rosell-dk commented Oct 24, 2019

Gd 2.2.5 has no such problems. I do not know about the versions between 2.1.1-dev and 2.2.5. Please contribute!

@rosell-dk
Copy link
Owner Author

Also reported on 2.1.1.

@rosell-dk
Copy link
Owner Author

For those that experiences this, here are your options:

  • Disable PNG. Gd isn't very good at converting PNG anyway, as Gd cannot create lossless webp, only lossy webp
  • Ask your host to upgrade Gd
  • Ask your host to install imagick, vips or cwebp
  • Use a cloud converter (ewww or connect to a remote webp-express / wpc)

@rosell-dk rosell-dk changed the title Old versions of Gd does not handle transparency (in some PNGs) Warn users on older versions of Gd, that it looses the alpha channel Jun 18, 2021
@ve3
Copy link

ve3 commented Mar 15, 2024

To be more specific, this GD's problem occur on prior PHP 7.0. It means PHP 5.6 or older.
Tested on Windows x86, x64.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants