PHP GD 擴充套件提供豐富的圖像處理能力。本文系統整理從資源建立、屬性取得、透明處理、縮放裁剪、水印、旋轉翻轉到銳化的完整函式與實戰代碼範例。
// 從零建立真彩色畫布
$img = imagecreatetruecolor($width, $height);
// 從現有檔案建立
$img = imagecreatefromjpeg('photo.jpg');
$img = imagecreatefrompng('logo.png');
$img = imagecreatefromgif('anim.gif');
$img = imagecreatefromwbmp('icon.wbmp');
$width = imagesx($img);
$height = imagesy($img);
// getimagesize 回傳陣列:[0]寬 [1]高 [2]類型常數 [3]HTML屬性字串
$info = getimagesize('photo.jpg');
// 類型常數:IMAGETYPE_GIF(1) JPG(2) PNG(3) SWF(4) PSD(5) BMP(6) TIFF(7/8) ...
// 將指定顏色設為透明 $transparent = imagecolortransparent($img); // 取得目前透明色索引 imagecolortransparent($img, $colorIndex); // 設定透明色 // 取得調色盤總色數 $total = imagecolorstotal($img); // 取得索引對應的 RGB $rgb = imagecolorsforindex($img, $index); // ['red'=>..., 'green'=>..., 'blue'=>..., 'alpha'=>...]
function thumbGif($src, $dst, $maxW, $maxH) {
list($w, $h) = getimagesize($src);
$ratio = min($maxW/$w, $maxH/$h);
$nw = (int)($w * $ratio);
$nh = (int)($h * $ratio);
$new = imagecreatetruecolor($nw, $nh);
$srcImg = imagecreatefromgif($src);
// 保留透明色
$transparent = imagecolortransparent($srcImg);
if ($transparent >= 0 && $transparent < imagecolorstotal($srcImg)) {
$rgb = imagecolorsforindex($srcImg, $transparent);
$newTransparent = imagecolorallocate($new, $rgb['red'], $rgb['green'], $rgb['blue']);
imagefill($new, 0, 0, $newTransparent);
imagecolortransparent($new, $newTransparent);
}
imagecopyresampled($new, $srcImg, 0, 0, 0, 0, $nw, $nh, $w, $h);
imagegif($new, $dst);
imagedestroy($new);
imagedestroy($srcImg);
}
// 縮放(較快、品質一般) imagecopyresized($dst, $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH); // 重採樣縮放(品質佳、較慢) imagecopyresampled($dst, $src, $dstX, $dstY, $srcX, $srcY, $dstW, $dstH, $srcW, $srcH); // 裁剪(從 src 取指定區域貼到 dst) imagecopy($dst, $src, $dstX, $dstY, $srcX, $srcY, $srcW, $srcH);
function thumbnail($src, $dst, $maxW, $maxH, $quality = 90) {
list($w, $h, $type) = getimagesize($src);
$ratio = min($maxW/$w, $maxH/$h);
$nw = (int)($w * $ratio);
$nh = (int)($h * $ratio);
$new = imagecreatetruecolor($nw, $nh);
$srcImg = match($type) {
IMAGETYPE_JPEG => imagecreatefromjpeg($src),
IMAGETYPE_PNG => imagecreatefrompng($src),
IMAGETYPE_GIF => imagecreatefromgif($src),
default => throw new Exception('Unsupported type'),
};
// PNG 保持透明通道
if ($type === IMAGETYPE_PNG) {
imagealphablending($new, false);
imagesavealpha($new, true);
}
imagecopyresampled($new, $srcImg, 0, 0, 0, 0, $nw, $nh, $w, $h);
match($type) {
IMAGETYPE_JPEG => imagejpeg($new, $dst, $quality),
IMAGETYPE_PNG => imagepng($new, $dst),
IMAGETYPE_GIF => imagegif($new, $dst),
};
imagedestroy($new);
imagedestroy($srcImg);
}
function watermarkText($src, $dst, $text, $fontFile, $size = 20, $color = [0,255,0], $x = 10, $y = 20) {
$img = imagecreatefromjpeg($src);
$color = imagecolorallocate($img, ...$color);
imagettftext($img, $size, 0, $x, $y, $color, $fontFile, $text);
imagejpeg($img, $dst);
imagedestroy($img);
}
function watermarkImage($src, $dst, $waterFile, $x, $y, $opacity = 100) {
$img = imagecreatefromjpeg($src);
$water = imagecreatefrompng($waterFile);
$ww = imagesx($water);
$wh = imagesy($water);
// 建立臨時畫布處理透明度
if ($opacity < 100) {
$temp = imagecreatetruecolor($ww, $wh);
imagecopy($temp, $water, 0, 0, 0, 0, $ww, $wh);
imagefilter($temp, IMG_FILTER_COLORIZE, 0, 0, 0, 127 - $opacity * 1.27);
$water = $temp;
}
imagecopy($img, $water, $x, $y, 0, 0, $ww, $wh);
imagejpeg($img, $dst);
imagedestroy($img);
imagedestroy($water);
}
// 逆時針旋轉角度,背景色用 0(黑)或分配的顏色 $rotated = imagerotate($srcImg, 45, 0); imagejpeg($rotated, 'rotated.jpg'); imagedestroy($rotated);
function flipHorizontal($src, $dst) {
$img = imagecreatefromjpeg($src);
$w = imagesx($img);
$h = imagesy($img);
$new = imagecreatetruecolor($w, $h);
for ($x = 0; $x < $w; $x++) {
imagecopy($new, $img, $w - $x - 1, 0, $x, 0, 1, $h);
}
imagejpeg($new, $dst);
imagedestroy($img);
imagedestroy($new);
}
function flipVertical($src, $dst) {
$img = imagecreatefromjpeg($src);
$w = imagesx($img);
$h = imagesy($img);
$new = imagecreatetruecolor($w, $h);
for ($y = 0; $y < $h; $y++) {
imagecopy($new, $img, 0, $h - $y - 1, 0, $y, $w, 1);
}
imagejpeg($new, $dst);
imagedestroy($img);
imagedestroy($new);
}
function sharpen($src, $dst, $degree = 20) {
$img = imagecreatefromjpeg($src);
$w = imagesx($img);
$h = imagesy($img);
$dstImg = imagecreatetruecolor($w, $h);
for ($x = 1; $x < $w - 1; $x++) {
for ($y = 1; $y < $h - 1; $y++) {
$curr = imagecolorsforindex($img, imagecolorat($img, $x, $y));
$prev = imagecolorsforindex($img, imagecolorat($img, $x - 1, $y - 1));
$r = min(255, max(0, intval($curr['red'] + $degree * ($curr['red'] - $prev['red']))));
$g = min(255, max(0, intval($curr['green'] + $degree * ($curr['green'] - $prev['green']))));
$b = min(255, max(0, intval($curr['blue'] + $degree * ($curr['blue'] - $prev['blue']))));
$color = imagecolorexact($dstImg, $r, $g, $b);
if ($color === -1) $color = imagecolorallocate($dstImg, $r, $g, $b);
imagesetpixel($dstImg, $x, $y, $color);
}
}
imagejpeg($dstImg, $dst);
imagedestroy($img);
imagedestroy($dstImg);
}
// 每個 imagecreate* 都必須配對 imagedestroy() imagedestroy($img); imagedestroy($new); // 否則記憶體洩漏,長時間運行的 CLI/Worker 會 OOM
GD 內建、無外部依賴、適合簡單縮放水印場景;複雜圖像處理、高併發、大圖建議升級 Imagick 或 Intervention Image。