| 函數 | GD 版本 | 算法 | 質量 | 速度 | 推薦場景 |
|---|---|---|---|---|---|
ImageCopyResized | 所有 | 最近鄰插值 | 鋸齒明顯 | 快 | 縮略圖、預覽、性能敏感 |
ImageCopyResampled | GD 2.0.1+ | 雙線性插值 | 邊緣平滑 | 較慢 | 正式展示圖、高質量需求 |
參數一致:dst, src, dx, dy, sx, sy, dw, dh, sw, sh (目標/源 資源、目標/源 坐標、目標/源 寬高)。
<?php
$srcPath = 'test.jpg';
$dstPath = 'thumb.jpg';
$scale = 0.5;
list($w, $h) = getimagesize($srcPath);
$nw = $w * $scale;
$nh = $h * $scale;
$src = imagecreatefromjpeg($srcPath);
$dst = imagecreatetruecolor($nw, $nh);
// 關鍵:保持透明通道 (PNG/GIF)
imagealphablending($dst, false);
imagesavealpha($dst, true);
imagecopyresampled($dst, $src, 0, 0, 0, 0, $nw, $nh, $w, $h);
imagejpeg($dst, $dstPath, 85); // 質量 85
imagedestroy($src);
imagedestroy($dst);
?>
<?php
function resizeImage($srcPath, $dstPath, $maxW, $maxH, $quality = 85, $crop = false) {
if (!file_exists($srcPath)) return false;
list($w, $h, $type) = getimagesize($srcPath);
$createFunc = [
IMAGETYPE_JPEG => 'imagecreatefromjpeg',
IMAGETYPE_PNG => 'imagecreatefrompng',
IMAGETYPE_GIF => 'imagecreatefromgif',
IMAGETYPE_WEBP => 'imagecreatefromwebp',
][$type] ?? null;
if (!$createFunc) return false;
$src = $createFunc($srcPath);
if ($crop) {
// 裁剪模式:填滿目標區域,居中裁剪
$ratio = max($maxW/$w, $maxH/$h);
$nw = $w * $ratio; $nh = $h * $ratio;
$sx = ($nw - $maxW) / 2 / $ratio;
$sy = ($nh - $maxH) / 2 / $ratio;
$sw = $maxW / $ratio; $sh = $maxH / $ratio;
$dw = $maxW; $dh = $maxH; $dx = $dy = 0;
} else {
// 等比縮放:完整顯示
$ratio = min($maxW/$w, $maxH/$h);
$nw = $w * $ratio; $nh = $h * $ratio;
$sx = $sy = 0; $sw = $w; $sh = $h;
$dw = $nw; $dh = $nh; $dx = $dy = 0;
}
$dst = imagecreatetruecolor($dw, $dh);
imagealphablending($dst, false);
imagesavealpha($dst, true);
imagecopyresampled($dst, $src, $dx, $dy, $sx, $sy, $dw, $dh, $sw, $sh);
$outputFunc = [
IMAGETYPE_JPEG => fn() => imagejpeg($dst, $dstPath, $quality),
IMAGETYPE_PNG => fn() => imagepng($dst, $dstPath, 9),
IMAGETYPE_GIF => fn() => imagegif($dst, $dstPath),
IMAGETYPE_WEBP => fn() => imagewebp($dst, $dstPath, $quality),
][$type];
$outputFunc();
imagedestroy($src); imagedestroy($dst);
return true;
}
?>
require 'SimpleImage.php';
$img = new \claviska\SimpleImage('photo.jpg');
$img->resize(300, 200) // 等比縮放至長邊 300
->crop(200, 200, 'center') // 中心裁剪正方形
->overlay('logo.png', 'bottom right', 10, 10, 0.5) // 水印
->save('output.jpg', 90);
GitHub: claviska/SimpleImage
<?php
function addWatermark($srcPath, $dstPath, $wmPath, $position = 'bottom-right', $opacity = 50, $margin = 10) {
$src = imagecreatefromstring(file_get_contents($srcPath));
$wm = imagecreatefrompng($wmPath); // 必須 PNG 透明
$srcW = imagesx($src); $srcH = imagesy($src);
$wmW = imagesx($wm); $wmH = imagesy($wm);
// 計算位置
$positions = [
'top-left' => [$margin, $margin],
'top-right' => [$srcW - $wmW - $margin, $margin],
'bottom-left' => [$margin, $srcH - $wmH - $margin],
'bottom-right' => [$srcW - $wmW - $margin, $srcH - $wmH - $margin],
'center' => [($srcW-$wmW)/2, ($srcH-$wmH)/2],
];
[$dx, $dy] = $positions[$position] ?? $positions['bottom-right'];
// 透明度合成 (PHP 5.4+ imagecopymerge_alpha 或手動混合)
imagealphablending($src, true);
imagecopymerge($src, $wm, $dx, $dy, 0, 0, $wmW, $wmH, $opacity);
imagepng($src, $dstPath);
imagedestroy($src); imagedestroy($wm);
}
// 使用
addWatermark('photo.jpg', 'watermarked.png', 'logo.png', 'bottom-right', 60);
?>
進階:文字水印用 imagettftext() 需 TTF 字體文件,支援旋轉、陰影、漸變。
memory_limit (如 256M+)。Imagick (ImageMagick PHP 擴展),多線程、格式支援更全、速度更快。