PHP มี Extension หลัก 2 ตัวสำหรับจัดการรูปภาพ: GD (มาตรฐาน, ติดตั้งง่าย) และ ImageMagick (ทรงพลังกว่า, รองรับฟอร์แมตมากกว่า) บทความนี้เน้น GD
ฟังก์ชันปรับขนาดรูปภาพครบวงจร
/**
* ปรับขนาดรูปภาพด้วย GD
*
* @param string $sourcePath ไฟล์ต้นทาง
* @param int $maxWidth ความกว้างสูงสุด
* @param int $maxHeight ความสูงสูงสุด
* @param bool $crop true = ตัดครอปให้พอดีขนาด, false = ย่อให้พอดีในกรอบ (คงสัดส่วน)
* @param int $quality คุณภาพ JPEG (0-100)
* @return resource|false Image Resource หรือ false ถ้าล้มเหลว
*/
function resizeImage($sourcePath, $maxWidth, $maxHeight, $crop = false, $quality = 85) {
// 1. ตรวจสอบไฟล์และอ่านข้อมูล
if (!file_exists($sourcePath)) {
throw new Exception("File not found: $sourcePath");
}
$imageInfo = getimagesize($sourcePath);
if (!$imageInfo) {
throw new Exception("Not a valid image file");
}
$srcWidth = $imageInfo[0];
$srcHeight = $imageInfo[1];
$mimeType = $imageInfo['mime'];
// 2. สร้าง Image Resource ตามประเภทไฟล์
switch ($mimeType) {
case 'image/jpeg':
$source = imagecreatefromjpeg($sourcePath);
break;
case 'image/png':
$source = imagecreatefrompng($sourcePath);
break;
case 'image/gif':
$source = imagecreatefromgif($sourcePath);
break;
case 'image/webp':
$source = imagecreatefromwebp($sourcePath);
break;
default:
throw new Exception("Unsupported image type: $mimeType");
}
if (!$source) {
throw new Exception("Failed to create image resource");
}
// 3. คำนวณขนาดใหม่
if ($crop) {
// โหมด Crop: ตัดให้พอดีขนาดเป๊ะๆ (อาจตัดส่วนข้าง/บนล่าง)
$srcRatio = $srcWidth / $srcHeight;
$dstRatio = $maxWidth / $maxHeight;
if ($srcRatio > $dstRatio) {
// รูปกว้างเกิน -> ตัดซ้าย/ขวา
$cropWidth = $srcHeight * $dstRatio;
$cropHeight = $srcHeight;
$srcX = ($srcWidth - $cropWidth) / 2;
$srcY = 0;
} else {
// รูปสูงเกิน -> ตัดบน/ล่าง
$cropWidth = $srcWidth;
$cropHeight = $srcWidth / $dstRatio;
$srcX = 0;
$srcY = ($srcHeight - $cropHeight) / 2;
}
$dstWidth = $maxWidth;
$dstHeight = $maxHeight;
} else {
// โหมด Fit: ย่อให้พอดีในกรอบ คงสัดส่วน
$ratio = min($maxWidth / $srcWidth, $maxHeight / $srcHeight);
$dstWidth = (int)round($srcWidth * $ratio);
$dstHeight = (int)round($srcHeight * $ratio);
$srcX = $srcY = 0;
$cropWidth = $srcWidth;
$cropHeight = $srcHeight;
}
// 4. สร้าง Destination Image
$dest = imagecreatetruecolor($dstWidth, $dstHeight);
// รองรับ Transparency (PNG, GIF, WebP)
if (in_array($mimeType, ['image/png', 'image/gif', 'image/webp'])) {
imagealphablending($dest, false);
imagesavealpha($dest, true);
$transparent = imagecolorallocatealpha($dest, 255, 255, 255, 127);
imagefilledrectangle($dest, 0, 0, $dstWidth, $dstHeight, $transparent);
}
// 5. Resample (คุณภาพดีกว่า Resize ธรรมดา)
imagecopyresampled(
$dest, $source,
0, 0, $srcX, $srcY,
$dstWidth, $dstHeight,
$cropWidth, $cropHeight
);
// 6. คืนค่า Resource (Caller ต้อง save เอง)
return $dest;
}
วิธีใช้งาน: บันทึกไฟล์
try {
// ปรับขนาดสูงสุด 800x600 คงสัดส่วน
$resized = resizeImage('uploads/photo.jpg', 800, 600, false, 90);
// บันทึกเป็น JPEG
imagejpeg($resized, 'uploads/photo_resized.jpg', 90);
// หรือบันทึกเป็น PNG
// imagepng($resized, 'uploads/photo_resized.png', 9);
// หรือ WebP (PHP 5.5+)
// imagewebp($resized, 'uploads/photo_resized.webp', 90);
// ปล่อยหน่วยความจำ
imagedestroy($resized);
echo "Resized successfully!";
} catch (Exception $e) {
echo "Error: " . $e->getMessage();
}
ตัวอย่าง: สร้าง Thumbnail แบบ Crop (Square)
$thumb = resizeImage('uploads/photo.jpg', 200, 200, true, 85);
imagejpeg($thumb, 'uploads/thumb_200x200.jpg', 85);
imagedestroy($thumb);
หมายเหตุสำคัญ
- Memory Limit: รูปภาพขนาดใหญ่ (เช่น 4000x3000 px) ใช้ RAM มาก ควรเพิ่ม
memory_limitใน php.ini - EXIF Orientation: รูปจากมือถือมักมี Orientation tag GD ไม่หมุนอัตโนมัติ ต้องใช้ Library เพิ่ม (เช่น lsolesen/exif)
- ImageMagick: สำหรับ Production ที่ต้องการประสิทธิภาพ/คุณภาพสูง แนะนำใช้
imagickextension แทน