首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP GD 縮放 GIF/PNG 透明背景變黑色問題解決

     編輯:PHP 相關知識

使用 imagecreatetruecolor() 創建真彩色畫布後,直接 imagecopyresampled() 貼圖,PNG/GIF 透明區域會變成**黑色**(預設填充色)。根因:真彩色畫布預設不支援 Alpha 通道,需顯式啟用透明度保存並填充全透明色。

錯誤代碼(透明變黑)

<?php
$src = imagecreatefrompng('logo.png');
$dst = imagecreatetruecolor(200, 200); // 預設黑色背景
imagecopyresampled($dst, $src, 0, 0, 0, 0, 200, 200, imagesx($src), imagesy($src));
imagepng($dst, 'logo_thumb.png'); // 輸出:透明區變黑
?>

正確三步驟

<?php
$src = imagecreatefrompng('logo.png');
$dst = imagecreatetruecolor(200, 200);

// 1. 關閉 Alpha 混色模式(避免與目標畫布混色)
imagealphablending($dst, false);

// 2. 分配全透明色 (R,G,B, Alpha=127 為完全透明)
$transparent = imagecolorallocatealpha($dst, 0, 0, 0, 127);

// 3. 填充整個畫布為透明
imagefill($dst, 0, 0, $transparent);

// 4. 關鍵:啟用 Alpha 通道保存(輸出時保留透明度)
imagesavealpha($dst, true);

// 現在可以安全縮放
imagecopyresampled($dst, $src, 0, 0, 0, 0, 200, 200, imagesx($src), imagesy($src));
imagepng($dst, 'logo_thumb.png'); // 輸出:透明完美保留

imagedestroy($src);
imagedestroy($dst);
?>

GIF 特殊處理

GIF 只支援**單色透明**(某一調色板索引完全透明),不支援半透明(Alpha 通道)。縮放 GIF 保持透明:

<?php
$src = imagecreatefromgif('icon.gif');
$dst = imagecreatetruecolor(100, 100);

// 獲取源圖透明色索引
$transparentIndex = imagecolortransparent($src);
if ($transparentIndex >= 0) {
    // 分配同樣 RGB 色作為目標透明色
    $rgb = imagecolorsforindex($src, $transparentIndex);
    $newTransparent = imagecolorallocate($dst, $rgb['red'], $rgb['green'], $rgb['blue']);
    imagefill($dst, 0, 0, $newTransparent);
    imagecolortransparent($dst, $newTransparent); // 設置目標圖透明色索引
}

imagecopyresampled($dst, $src, 0, 0, 0, 0, 100, 100, imagesx($src), imagesy($src));
imagegif($dst, 'icon_thumb.gif');
?>

通用封裝函數

<?php
/**
 * 縮放圖片並保留透明度
 * @param string $srcPath 源文件
 * @param string $dstPath 目標文件
 * @param int $maxW 最大寬
 * @param int $maxH 最大高
 * @return bool
 */
function smart_resize(string $srcPath, string $dstPath, int $maxW, int $maxH): bool {
    $info = getimagesize($srcPath);
    if (!$info) return false;
    [$srcW, $srcH, $type] = $info;
    
    // 計算目標尺寸(等比)
    $ratio = min($maxW / $srcW, $maxH / $srcH);
    $dstW = (int)($srcW * $ratio);
    $dstH = (int)($srcH * $ratio);
    
    // 創建源圖資源
    $createFrom = ['gif'=>'imagecreatefromgif','jpeg'=>'imagecreatefromjpeg','png'=>'imagecreatefrompng','webp'=>'imagecreatefromwebp'];
    $func = $createFrom[image_type_to_extension($type, false)] ?? null;
    if (!$func) return false;
    $src = $func($srcPath);
    
    // 創建目標畫布並設置透明
    $dst = imagecreatetruecolor($dstW, $dstH);
    imagealphablending($dst, false);
    $transparent = imagecolorallocatealpha($dst, 0, 0, 0, 127);
    imagefill($dst, 0, 0, $transparent);
    imagesavealpha($dst, true);
    
    // GIF 額外處理單色透明
    if ($type === IMAGETYPE_GIF) {
        $ti = imagecolortransparent($src);
        if ($ti >= 0) {
            $rgb = imagecolorsforindex($src, $ti);
            $nt = imagecolorallocate($dst, $rgb['red'], $rgb['green'], $rgb['blue']);
            imagefill($dst, 0, 0, $nt);
            imagecolortransparent($dst, $nt);
        }
    }
    
    // 縮放
    imagecopyresampled($dst, $src, 0, 0, 0, 0, $dstW, $dstH, $srcW, $srcH);
    
    // 輸出
    $output = ['gif'=>'imagegif','jpeg'=>'imagejpeg','png'=>'imagepng','webp'=>'imagewebp'];
    $outFunc = $output[image_type_to_extension($type, false)];
    $result = $outFunc($dst, $dstPath);
    
    imagedestroy($src);
    imagedestroy($dst);
    return $result;
}
?>
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved