I need to resize a picture to a fixed size. But it has to keep the factors between the width and height.
Say I want to resize a picture from 238 (w) X 182 (h)
to 210 / 150
What I do now is:
Original width / target width = 1.333333
Original Height / target Height = 1.213333
Now I take the smallest factor.
Now I always have the right width since 238 / 1.333333 = 210
.
But the height is still 160
.
How do I get the height down to 160
without ruining the pic?
Do I need to crop? If so how?
One way to do this is to use a program like Photoshop. With Photoshop, you can resize an image without losing quality by using the "Image Size" dialog box. In the "Image Size" dialog box, you can change the width and height of the image. You can also change the resolution.
Crop Image to an Aspect RatioClick Upload an image and select the image you want to crop. Under step 2, click the Fixed Aspect Ratio button, then enter that ratio, such as 5 and 2, and click Change. Drag a rectangle over the image to select the area you want. Move the selection as needed, then click Crop.
This solution is basically the same as Can Berk Güder's, but after having spent some time writing and commenting, I felt like posting.
This function creates a thumbnail that is exactly as big as the size you give it. The image is resized to best fit the size of the thumbnail. If it does not fit exactly in both directions, it's centered in the thumnail. Extensive comments explain the goings-on.
function thumbnail_box($img, $box_w, $box_h) {
//create the image, of the required size
$new = imagecreatetruecolor($box_w, $box_h);
if($new === false) {
//creation failed -- probably not enough memory
return null;
}
//Fill the image with a light grey color
//(this will be visible in the padding around the image,
//if the aspect ratios of the image and the thumbnail do not match)
//Replace this with any color you want, or comment it out for black.
//I used grey for testing =)
$fill = imagecolorallocate($new, 200, 200, 205);
imagefill($new, 0, 0, $fill);
//compute resize ratio
$hratio = $box_h / imagesy($img);
$wratio = $box_w / imagesx($img);
$ratio = min($hratio, $wratio);
//if the source is smaller than the thumbnail size,
//don't resize -- add a margin instead
//(that is, dont magnify images)
if($ratio > 1.0)
$ratio = 1.0;
//compute sizes
$sy = floor(imagesy($img) * $ratio);
$sx = floor(imagesx($img) * $ratio);
//compute margins
//Using these margins centers the image in the thumbnail.
//If you always want the image to the top left,
//set both of these to 0
$m_y = floor(($box_h - $sy) / 2);
$m_x = floor(($box_w - $sx) / 2);
//Copy the image data, and resample
//
//If you want a fast and ugly thumbnail,
//replace imagecopyresampled with imagecopyresized
if(!imagecopyresampled($new, $img,
$m_x, $m_y, //dest x, y (margins)
0, 0, //src x, y (0,0 means top left)
$sx, $sy,//dest w, h (resample to this size (computed above)
imagesx($img), imagesy($img)) //src w, h (the full size of the original)
) {
//copy failed
imagedestroy($new);
return null;
}
//copy successful
return $new;
}
Example usage:
$i = imagecreatefromjpeg("img.jpg");
$thumb = thumbnail_box($i, 210, 150);
imagedestroy($i);
if(is_null($thumb)) {
/* image creation or copying failed */
header('HTTP/1.1 500 Internal Server Error');
exit();
}
header('Content-Type: image/jpeg');
imagejpeg($thumb);
This doesn't crop the picture, but leaves space around the new image if necessary, which I think is a better approach (than cropping) when creating thumbnails.
$w = 210;
$h = 150;
$orig_w = imagesx($original);
$orig_h = imagesy($original);
$w_ratio = $orig_w / $w;
$h_ratio = $orig_h / $h;
$ratio = $w_ratio > $h_ratio ? $w_ratio : $h_ratio;
$dst_w = $orig_w / $ratio;
$dst_h = $orig_h / $ratio;
$dst_x = ($w - $dst_w) / 2;
$dst_y = ($h - $dst_h) / 2;
$thumbnail = imagecreatetruecolor($w, $h);
imagecopyresampled($thumbnail, $original, $dst_x, $dst_y,
0, 0, $dst_w, $dst_h, $orig_w, $orig_h);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With