简而言之: 为了减小文件大小,您的PNG图像已使用调色板(例如256种颜色)进行导出。透明度信息可能无法准确保留。这是因为基于调色板的颜色减少技术主要设计用于保留颜色信息而非透明度。为确保透明度得到保留,通常建议使用完全支持颜色的PNG图像(32位RGBA)进行导出,而不是使用有限颜色的调色板。
![comparison](https://istack.dev59.com/ciQbA.webp)
你可以尝试使用RGBA格式和下面找到的代码。
免责声明:我正在使用PHP 8.1.6和libPNG:1.6.37在macOS(Intel,Ventura 13.2.1(22D68))上,并且它可以正常工作。
前提条件:
我已确保您的帧首先在Affinity Photo中是100%透明的,我使用了填充工具手动删除了这些区域。我还使用默认设置导出了图像。如果我使用您的图像,最终会得到一个alpha值为229。
![reconstruct](https://istack.dev59.com/uM65y.webp)
在浏览器中显示 / MIME 类型:
当使用 header('Content-Type: image/png')
渲染时,浏览器会为图像添加一些样式和类(浏览器中的默认样式)。我们只请求浏览器渲染孤立的图像,但浏览器会添加一些其他东西使其看起来“好看”-请参见屏幕截图中的 DOM。
例如,在 Firefox 中,您可以看到添加的“透明”类-它添加了一个背景(我已在第一个屏幕截图中禁用此功能)。如果我们将其更改为红色,则可以看到背景现在是红色的,因此框架也是红色的,因为它们是100%透明的。
![preview-2](https://istack.dev59.com/FpKKm.webp)
那么我们该如何解决这个问题呢?这取决于你想要做什么。基本上,你可以渲染自己的HTML文档,而不是使用“mime-type: image/png”,这样就没有浏览器默认值了。
例如:
<?php
$image = imagecreatefrompng('./test-img.png');
imagealphablending($image, true);
$trimmed = imagecropauto($image, IMG_CROP_SIDES);
$generatedImagePath = './test-img-generated.png';
if ($trimmed !== false) {
imagesavealpha($trimmed, true);
imagepng($trimmed, $generatedImagePath);
} else {
echo "Failed to crop the image.";
}
imagedestroy($image);
imagedestroy($trimmed);
?>
<!DOCTYPE html>
<html>
<body style="background: transparent; background-image: url('./pattern.jpg')">
<img src="<?php echo $generatedImagePath; ?>" style="width: 480px; aspect-ratio: 1;">
</body>
</html>
渲染:
![prove](https://istack.dev59.com/UFUoT.webp)