Tự động giảm kích thước ảnh về giới hạn với PHP

Khi làm việc với hệ thống upload ảnh — chẳng hạn như blog cá nhân, hệ thống CMS, hoặc thư viện ảnh — bạn nên giới hạn kích thước ảnh để tiết kiệm băng thông, dung lượng ổ đĩa, đồng thời tăng tốc độ tải trang.

Tự động giảm kích thước ảnh về giới hạn với PHP

Bài viết này sẽ giúp bạn tự động resize ảnh JPG về kích thước mong muốn bằng PHP thuần, không cần thư viện ngoài.

Mục tiêu

  • Tự động giảm kích thước ảnh theo chiều rộng/cao giới hạn
  • Duy trì tỷ lệ ảnh gốc (không bị méo)
  • Hỗ trợ chất lượng ảnh đầu ra (JPEG quality)
  • Ghi đè ảnh gốc hoặc lưu vào file mới

Hàm xử lý resize ảnh

Đầu tiên, bạn thêm hàm này. Lưu ý là hàm này chỉ xử lí định dạng ảnh JPG.

function resize_image($source_image, $target_image, $max_width, $max_height = 0, $quality = 90) {
    if (!file_exists($source_image)) return false;

    $image_info = getimagesize($source_image);
    if (!$image_info) return false;

    [$orig_width, $orig_height, $image_type] = $image_info;

    switch ($image_type) {
        case IMAGETYPE_JPEG:
            $image = imagecreatefromjpeg($source_image);
            break;
        case IMAGETYPE_PNG:
            $image = imagecreatefrompng($source_image);
            break;
        case IMAGETYPE_GIF:
            $image = imagecreatefromgif($source_image);
            break;
        default:
            return false;
    }

    if (!$image) return false;

    // Kích thước tối đa
    $max_width = $max_width > 0 ? $max_width : $orig_width;
    $max_height = $max_height > 0 ? $max_height : $orig_height;

    // Tính tỷ lệ resize
    $ratio = min($max_width / $orig_width, $max_height / $orig_height);
    $new_width  = (int) ($orig_width * $ratio);
    $new_height = (int) ($orig_height * $ratio);

    $new_image = imagecreatetruecolor($new_width, $new_height);

    // Xử lý alpha cho PNG và GIF
    if ($image_type == IMAGETYPE_PNG || $image_type == IMAGETYPE_GIF) {
        imagealphablending($new_image, false);
        imagesavealpha($new_image, true);
        $transparent = imagecolorallocatealpha($new_image, 0, 0, 0, 127);
        imagefill($new_image, 0, 0, $transparent);
    }

    imagecopyresampled($new_image, $image, 0, 0, 0, 0, $new_width, $new_height, $orig_width, $orig_height);

    // Lưu hình
    switch ($image_type) {
        case IMAGETYPE_JPEG:
            imagejpeg($new_image, $target_image, $quality);
            break;
        case IMAGETYPE_PNG:
            imagepng($new_image, $target_image);
            break;
        case IMAGETYPE_GIF:
            imagegif($new_image, $target_image);
            break;
    }

    imagedestroy($image);
    imagedestroy($new_image);

    return ['w' => $new_width, 'h' => $new_height];
}

Cách sử dụng

Để sử dụng, bạn gọi lại hàm trên. Ví dụ mình cắt ảnh thumbnail.jpg về kích thước 750px và giảm chất lượng còn 80%.

$filepath = 'img/thumbnail.jpg';

// Đảm bảo file tồn tại
if (!file_exists($filepath)) {
    error_log("File không tồn tại: $filepath");
    return;
}

// Tạo đường dẫn thumbnail dựa trên kích thước
$thumb_path = preg_replace('/(\.\w+)$/', '-750w$1', $filepath);

// Nếu thumbnail chưa tồn tại, tạo mới
if (!file_exists($thumb_path)) {
    $image_size = resize_image($filepath, $thumb_path, 750, 0, 80);
} else {
    $image_size = getimagesize($thumb_path);
    $image_size = ['w' => $image_size[0], 'h' => $image_size[1]];
}
  • $filepath: đường dẫn đến file ảnh
  • 750: chiều rộng tối đa bạn cho phép
  • 0: không giới hạn chiều cao (giữ theo tỉ lệ)
  • 80: chất lượng ảnh đầu ra (1–100)

Lưu ý

  • Chỉ hỗ trợ ảnh .jpg hoặc .jpeg. Bạn có thể mở rộng sang PNG hoặc WebP nếu cần
  • File đầu ra sẽ ghi đè file gốc nếu $source_image === $target_image. Hãy cẩn thận nếu bạn cần giữ bản gốc
  • Hàm sử dụng GD Library, mặc định có sẵn trên hầu hết server PHP

Ứng dụng thực tế

  • Resize ảnh tải lên từ người dùng
  • Tạo phiên bản ảnh nhỏ (thumbnail) để hiển thị nhanh
  • Tối ưu SEO ảnh (tốc độ tải, kích thước nhẹ)

Chúc các bạn thành công!

Bình Luận


  • Không có bình luận.