Reputation: 4201
What would be the best way to resize images, which could be of any dimension, to a fixed size, or at least to fit within a fixed size?
The images come from random urls that are not in my control, and I must ensure the images do not go out of an area roughly 250px x 300px, or 20% by 50% of a layer.
I would think that I would first determine the size, and if it fell outside the range, resize by a factor, but I am unsure how to work out the logic to resize if the image size could be anything.
edit:I do not have local access to the image, and the image url is in a variable with is output with img src=..., I need a way to specify the values of width and height tags.
Upvotes: 3
Views: 4350
Reputation: 9550
I created the following function to do intelligent resizing of images with respect to ratio and even has a parameter to upscale smaller images (which is critical if your HTML layout screws up when thumbnails are wierd sizes).
function ImageIntelligentResize( $imagePath, $maxWidth, $maxHeight, $alwaysUpscale )
{
// garbage in, garbage out
if ( IsNullOrEmpty($imagePath) || !is_file($imagePath) || IsNullOrEmpty($maxWidth) || IsNullOrEmpty($maxHeight) )
{
return array("width"=>"", "height"=>"");
}
// if our thumbnail size is too big, adjust it via HTML
$size = getimagesize($imagePath);
$origWidth = $size[0];
$origHeight = $size[1];
// Check if the image we're grabbing is larger than the max width or height or if we always want it resized
if ( $alwaysUpscale || $origWidth > $maxWidth || $origHeight > $maxHeight )
{
// it is so let's resize the image intelligently
// check if our image is landscape or portrait
if ( $origWidth > $origHeight )
{
// target image is landscape/wide (ex: 4x3)
$newWidth = $maxWidth;
$ratio = $maxWidth / $origWidth;
$newHeight = floor($origHeight * $ratio);
// make sure the image wasn't heigher than expected
if ($newHeight > $maxHeight)
{
// it is so limit by the height
$newHeight = $maxHeight;
$ratio = $maxHeight / $origHeight;
$newWidth = floor($origWidth * $ratio);
}
}
else
{
// target image is portrait/tall (ex: 3x4)
$newHeight = $maxHeight;
$ratio = $maxHeight / $origHeight;
$newWidth = floor($origWidth * $ratio);
// make sure the image wasn't wider than expected
if ($newWidth > $maxWidth)
{
// it is so limit by the width
$newWidth = $maxWidth;
$ratio = $maxWidth / $origWidth;
$newHeight = floor($origHeight * $ratio);
}
}
}
// it's not, so just use the current height and width
else
{
$newWidth = $origWidth;
$newHeight = $origHeight;
}
return array("width"=>$newWidth, "height"=>$newHeight);
}
Upvotes: 0
Reputation: 6504
It's easy to do with ImageMagick. Either you use convert command line tool via exec or you use http://www.francodacosta.com/phmagick/resizing-images .
If you use 'convert' you can even tell ImageMagick to just resize larger images and to not convert smaller ones: http://www.imagemagick.org/Usage/resize/
If you don't have local access, you won't be able to use ImageMagick:
<?php
$maxWidth = 250;
$maxHeight = 500;
$size = getimagesize($url);
if ($size) {
$imageWidth = $size[0];
$imageHeight = $size[1];
$wRatio = $imageWidth / $maxWidth;
$hRatio = $imageHeight / $maxHeight;
$maxRatio = max($wRatio, $hRatio);
if ($maxRatio > 1) {
$outputWidth = $imageWidth / $maxRatio;
$outputHeight = $imageHeight / $maxRatio;
} else {
$outputWidth = $imageWidth;
$outputHeight = $imageHeight;
}
}
?>
Upvotes: 5
Reputation: 1099
If you have to keep the aspect ratio of the image intact then you should scale it by a factor so that the longer side of the image (height or width) fits inside the limitations for that side.
Upvotes: 1
Reputation: 288
I'm not sure of the exact solution to your answer, but I know a project written in PHP which has the solution. Go and take a look at the ImageCache built for the Drupal CMS, which is written in PHP.
It basically let's you define some actions to take on an arbitrary image, and produce almost whatever scaling/cropping you want to the image.
You'd have to learn a few of the Drupal API's to be able to understand this example, but it is extensive and if you understand their algorithms, you'd be able to solve other more complicated problems.
Upvotes: 0
Reputation: 12726
Have you looked at the GD library documentation, particularly the imagecopyresized method?
Upvotes: 1
Reputation: 655735
You could use the following:
$maxWidth = 250;
$maxHeight = 500;
$validSize = true;
$imageinfo = getimagesize($filename);
if ($imageinfo) {
$validSize &= $imageinfo[0] <= $maxWidth;
$validSize &= $imageinfo[1] <= $maxHeight;
}
The &=
is a combined operator of the bitwise-and operator &
and the assignment operator =
. Thus $foo &= *expr*
and $foo = $foo & *expr*
are equivalent.
Upvotes: 0