Last updated: August 29, 2026.
Generate thumbnails during upload or in a background job. Preserve the aspect ratio and resample the source instead of stretching it.
Resize and encode
<?php
$source = imagecreatefromjpeg(__DIR__ . '/photo.jpg');
if ($source === false) throw new RuntimeException('Invalid JPEG.');
$width = imagesx($source); $height = imagesy($source);
$newWidth = min(480, $width);
$newHeight = (int) round($height * $newWidth / $width);
$thumb = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($thumb, $source, 0, 0, 0, 0, $newWidth, $newHeight, $width, $height);
if (!imagewebp($thumb, __DIR__ . '/photo-thumb.webp', 82)) throw new RuntimeException('Write failed.');
imagedestroy($source); imagedestroy($thumb);Production checks
- Confirm that GD includes WebP support.
- Cap source dimensions to control memory use.
- Keep the original when later edits may need it.
- Test visual quality on photos and graphics.
Preserve proportions and metadata decisions
Calculate the thumbnail height from the original aspect ratio and decide whether orientation should be normalized first. A thumbnail generator should reject unreasonable source dimensions before allocating a large image buffer.
Compare output dimensions and file size, then inspect photos, screenshots, transparency, and very small originals. Confirm that a failed write does not leave a partial file marked as complete.
- Check GD WebP support.
- Normalize EXIF orientation first.
- Keep a fallback format when required.
Keep resource limits explicit and make failure cleanup part of the example. Log enough context to diagnose the operation without recording passwords, private message bodies, or uploaded file contents.
Continue with thumbnail fundamentals, EXIF rotation, and AVIF conversion.
Practical implementation check
Put the operation in a small function or service with explicit inputs and a clear failure result. Test invalid input, missing extensions, permission failures, and concurrent requests. Production logs should identify the operation and record ID without storing secrets or private content. Clean up partially created files or queue records when any later step fails.
Reference: PHP imagewebp reference.