PHP imagecopyresampled填充全目标图问题及源图等比缩放需求
imagecopyresampled to Fill Only a Partial Area of the Target Image Hey there! I get exactly what you're dealing with—imagecopyresampled has a tendency to stretch your source to fit the entire target if you're not careful, but we can tweak the parameters to get the exact partial fill you want. Let's break this down step by step.
First, Calculate the Correct Scaled Dimensions
Your source is 344px wide × 86px tall, and you want to scale it proportionally to 64px wide. Let's compute the scaled height first:
$sourcePath = $_FILES['file_to_upload']['tmp_name']; list($sourceWidth, $sourceHeight) = getimagesize($sourcePath); // Target canvas size (64x64 blank image) $targetCanvasWidth = 64; $targetCanvasHeight = 64; // Calculate proportional scaled size (lock width to 64px) $scaledSourceWidth = 64; $scaledSourceHeight = round($sourceHeight * ($scaledSourceWidth / $sourceWidth)); // For your numbers, this works out to exactly 16px tall—perfect!
Create Your Image Resources
Next, set up your source image and the blank target canvas. Don't forget to handle transparency if you need a non-solid background (like PNGs):
// Load the source image (adjust the function if you're using PNG/GIF: imagecreatefrompng/imagecreatefromgif) $sourceImage = imagecreatefromjpeg($sourcePath); // Create the blank 64x64 target canvas $targetCanvas = imagecreatetruecolor($targetCanvasWidth, $targetCanvasHeight); // Optional: Add transparent background if you need it (for PNG outputs) imagealphablending($targetCanvas, false); imagesavealpha($targetCanvas, true); $transparentColor = imagecolorallocatealpha($targetCanvas, 0, 0, 0, 127); imagefill($targetCanvas, 0, 0, $transparentColor);
The Key: Use imagecopyresampled to Draw Only the Scaled Area
This is where you were probably going wrong before—instead of stretching the scaled source to fill the entire 64x64 canvas, we'll draw it only in the section we want (like the top, or centered):
// Choose where to place the scaled source on the target canvas // Example 1: Align to the top (y=0) $destX = 0; $destY = 0; // Example 2: Center vertically (uncomment this if you want centered placement) // $destY = ($targetCanvasHeight - $scaledSourceHeight) / 2; // Perform the resampling and partial copy imagecopyresampled( $targetCanvas, // The target canvas we're drawing onto $sourceImage, // The original source image $destX, $destY, // Starting coordinates on the target canvas 0, 0, // Starting coordinates on the source image (we want the whole thing) $scaledSourceWidth, $scaledSourceHeight, // Size to draw on the target (our scaled dimensions) $sourceWidth, $sourceHeight // Size to take from the source (full original size) );
Output or Save Your Final Image
Finally, render the result or save it to a file:
// Output to browser (adjust content type for PNG/GIF) header('Content-Type: image/png'); imagepng($targetCanvas); // Or save to a file: // imagepng($targetCanvas, 'path/to/your/output.png'); // Clean up resources to free memory imagedestroy($sourceImage); imagedestroy($targetCanvas);
Why This Works
By specifying $scaledSourceWidth and $scaledSourceHeight as the dimensions to draw on the target, we're telling imagecopyresampled to only fill that small 64x16 area of the 64x64 canvas—no stretching required. The rest of the canvas stays blank (or transparent, if you set that up).
内容的提问来源于stack exchange,提问作者Andris




