tags:

views:

732

answers:

6

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.

A: 

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.

Gumbo
I don't think I understand your example, would you be able to explain it a bit more?
Joshxtothe4
Gumbo
+3  A: 

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;
    }
}
?>
Sven Lilienthal
phMagick looks good, however I don't have direct access to the image. It is coming from a url which is stored in a variable, which is displayed with img src=...
Joshxtothe4
I edited my answer to deal with non-local images. Hope it helps you.
Sven Lilienthal
Which of these functions are from phmagick, is phmagick still necessary? Your example is quite different from the one at http://www.francodacosta.com/phmagick/resizing-images
Joshxtothe4
Sorry, edited the answer. ImageMagick is only useful if you have full access to the image. If you include the image via an img-tag in your html, you won't be able to use it.
Sven Lilienthal
the Imagick extension for PHP is able to load imagedata from a raw string. Meaning, you can file_get_contents() the image and then modify it.
jishi
But then you would have to either save the image locally or create another php-script which would then deliver the modified image by reading it from the url, modifying it in-memory and writing it to the user.
Sven Lilienthal
I am trying this example now, but it does not seem to make a difference. I am trying with <img src='".$lastImg."' width=".$outputWidth."' height=".$outputHeight."'>(part of a bigger string) which outputs <img src='http://i10.ebayimg.com/08/i/001/1d/10/8d15_1.JPG?set_id=800005007' width=' height='> ?
Joshxtothe4
It seems to be because size is always empty.., do I have to include something to use getimagesize?
Joshxtothe4
You can include die(print_r(error_get_last()));in the else block to get debug output.
Sven Lilienthal
No error is output at all.
Joshxtothe4
I have no idea. The script works for me.
Sven Lilienthal
A: 

Have you looked at the GD library documentation, particularly the imagecopyresized method?

Tim Almond
A: 

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.

David Wees
+2  A: 

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.

Alo
A: 

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);
}
TravisO