How to Create Thumbnail Images in PHP with GD

Last updated: August 29, 2026.

PHP’s GD extension can create proportional thumbnails for JPEG, PNG, and WebP images. The function below fits an image inside a maximum width and height, preserves transparency where supported, and avoids enlarging small images.

Requirements

  • PHP with the GD extension enabled.
  • A readable source file and a writable thumbnail directory.
  • Enough memory for the decoded image, which can be much larger than the compressed upload.

Create a proportional thumbnail

<?php
function createThumbnail(
    string $sourcePath,
    string $destinationPath,
    int $maxWidth,
    int $maxHeight
): void {
    if ($maxWidth < 1 || $maxHeight < 1) {
        throw new InvalidArgumentException('Thumbnail dimensions must be positive.');
    }

    if (!is_file($sourcePath) || !is_readable($sourcePath)) {
        throw new RuntimeException('Source image is not readable.');
    }

    if (filesize($sourcePath) > 20 * 1024 * 1024) {
        throw new RuntimeException('Source image is too large.');
    }

    $data = file_get_contents($sourcePath);
    $source = $data === false ? false : @imagecreatefromstring($data);

    if ($source === false) {
        throw new RuntimeException('Unsupported or invalid image.');
    }

    $sourceWidth = imagesx($source);
    $sourceHeight = imagesy($source);

    if ($sourceWidth * $sourceHeight > 40_000_000) {
        imagedestroy($source);
        throw new RuntimeException('Image dimensions are too large.');
    }

    $scale = min(
        $maxWidth / $sourceWidth,
        $maxHeight / $sourceHeight,
        1
    );

    $thumbWidth = max(1, (int) floor($sourceWidth * $scale));
    $thumbHeight = max(1, (int) floor($sourceHeight * $scale));
    $thumbnail = imagecreatetruecolor($thumbWidth, $thumbHeight);

    $format = strtolower(pathinfo($destinationPath, PATHINFO_EXTENSION));
    if (!in_array($format, ['jpg', 'jpeg', 'png', 'webp'], true)) {
        imagedestroy($source);
        imagedestroy($thumbnail);
        throw new InvalidArgumentException('Use JPG, PNG, or WebP output.');
    }

    if ($format === 'png' || $format === 'webp') {
        imagealphablending($thumbnail, false);
        imagesavealpha($thumbnail, true);
        $transparent = imagecolorallocatealpha($thumbnail, 0, 0, 0, 127);
        imagefill($thumbnail, 0, 0, $transparent);
    } else {
        $white = imagecolorallocate($thumbnail, 255, 255, 255);
        imagefill($thumbnail, 0, 0, $white);
    }

    imagecopyresampled(
        $thumbnail,
        $source,
        0,
        0,
        0,
        0,
        $thumbWidth,
        $thumbHeight,
        $sourceWidth,
        $sourceHeight
    );

    $saved = match ($format) {
        'jpg', 'jpeg' => imagejpeg($thumbnail, $destinationPath, 85),
        'png' => imagepng($thumbnail, $destinationPath, 6),
        'webp' => imagewebp($thumbnail, $destinationPath, 82),
    };

    imagedestroy($source);
    imagedestroy($thumbnail);

    if (!$saved) {
        throw new RuntimeException('The thumbnail could not be saved.');
    }
}

imagecopyresampled() performs smooth resampling, which produces better reduced images than a simple pixel resize. The destination file extension selects JPG, PNG, or WebP output.

Call the function

<?php
$source = __DIR__ . '/uploads/photo.jpg';
$destination = __DIR__ . '/thumbnails/photo.webp';

createThumbnail($source, $destination, 480, 320);

The result fits inside 480 × 320 pixels while retaining its aspect ratio. Create the destination directory before calling the function and give the PHP process permission to write there.

Handling uploaded images safely

  • Enforce both compressed file-size and decoded pixel limits.
  • Use Fileinfo and an actual image decoder; do not trust the browser-provided MIME type or filename extension.
  • Generate destination filenames on the server.
  • Store uploads where PHP files cannot execute.
  • Reject unreadable, unsupported, or corrupt files without displaying internal paths to visitors.

Phone-photo orientation

JPEG photos may store rotation in EXIF metadata. If phone uploads appear sideways, read the orientation with exif_read_data() and rotate the source before calculating the thumbnail dimensions.

Useful GD references

Modern image-processing guides

After creating a basic thumbnail, use these guides for current formats, orientation, and upload previews.

admin

admin

2 thoughts on “How to Create Thumbnail Images in PHP with GD

  1. This works great thanks.
    It does create very low quality thumbnails though. How would I go about creating better quality ones? It seems the resizing algorithm here is a basic pixel resize one rather than the ones that give smoother results.

Leave a Reply

Your email address will not be published.