Help resizing an image

Hi all,

I’m really struggling here and was wondering whether someone would be kind enough to help me, now the codes a little messy at the moment, but I just want to get the dam thing working.

Essentially no matter what the size of the image is I want to resize it to 140(w)x200(h) at the same time keeping the scale.

Now the way I thought of doing it is as follows, if we take a landscape image as an example (600x400). As the width is bigger than the height I’m going to scale the image to 200px in height so this would be 300px in width so I then want to crop from either side to 140px, I hope I make sense…I’m feeling shattered!!!

This is code I’ve got so far, I’m almost there, I’m just struggling with cropping part???


function createCroppedImage($img,$maxWidth,$maxHeight,$filename)
{
	$adjust       = NULL;
	$resizeWidth  = NULL;
	$resizeHeight = NULL;
	$cropWidth    = NULL;
	$cropHeight   = NULL;
	
	$crop = false;
	
	$width  = imagesx($img);
	$height = imagesy($img);

	// Work out if image is landscape or portrait
	if($width>$height)
	{
		$scale = $height/$maxHeight;
	}
	else
	{
		$scale = $width/$maxWidth;
	}

	$resizeWidth   = ($width/$scale  < $maxwidth)  ? $maxWidth  : $width/$scale;
	$resizeHeight  = ($height/$scale < $maxHeight) ? $maxHeight : $height/$scale;

	$sample = imagecreatetruecolor($resizeWidth, $resizeHeight);

	imagecopyresampled($sample, $img, 0, 0, 0, 0, $resizeWidth, $resizeHeight, $width, $height);
   	imagejpeg($sample,$filename . ".jpg",100);
	imagedestroy($sample);

	// We need to crop the width
	if($resizeWidth>$maxWidth)
	{
		$crop       = true;
		$adjust     = $resizeWidth-$maxWidth;
		$cropWidth  = $resizeWidth-$adjust;
		$cropHeight = $resizeHeight;
		$x          = 0;
		$y          = 0;
	}
	
        if($crop)
	{
		$img = imagecreatefromjpeg($filename . ".jpg");
		$sample = imagecreatetruecolor($cropWidth, $cropHeight);
		imagecopyresampled($sample, $img, 0, 0, 0, 0, $cropWidth, $cropHeight, $resizeWidth, $resizeHeight);
	   	imagejpeg($sample,$filename . ".jpg",100);
		imagedestroy($sample);
	}
}

It seems to be squashing the image rather than crop?

Any help would be much appreciated

Crabby

Agreed. :wink:

Nice. But I would rename the Filter interface to Transformation (and all classes that implement it, GrayScaleTransformation, ResizeTransformation and so on). It just sounds better and you said it yourself:

We basically, create the image then pass it through an object to apply the various transformations required
.

Get the math down first, work on the formula to get the desired outcome given any size. Then, once complete, throw in the code.

I’m pretty sure I’ve worked out the math, I’m just stuck on the code with the cropping

I wasn’t having ‘a pop’ at your math - just in case that’s what came across. :wink:

Whilst not a direct solution, I like to do this sort of this in steps, gradually building up the desired product.

Here’s a way to do that which I’ve found to be quite flexible, if you can stand the OOP. :smiley:


$image = new Image('Penguins.jpg');

$filter = new FilterChain();
$filter->addFilter(new GrayScaleFilter());
$filter->addFilter(new ResizeFilter(25));

$image = $filter->filter($image);

header('Content-Type: image/jpeg');
imagejpeg($image->getResource());

We basically, create the image then pass it through an object to apply the various transformations required. It allows you (maybe me) to focus a little on the job in hand. Plus, if you find it all goes wrong, its much easier to track down the offending element.

Try creating a filter to add a watermark, or rotate the image etc… It’s a nice way to code. I think. :stuck_out_tongue:

Here’s a quick, untested set of objects that do the above.


<?php
class Image
{
  protected
    $image;
    
  public function __construct($file){
    $this->image = imagecreatefromjpeg($file);
  }
  
  public function getResource(){
    return $this->image;
  }
  
  public function setResource($resource){
    $this->image = $resource;
    return $this;
  }
  
  public function getWidth(){
    return imagesx($this->getResource());
  }
  
  public function getHeight(){
    return imagesy($this->getResource());
  }
}

interface IFilter
{
  public function filter(Image $image);
}

class FilterChain implements IFilter
{
  protected
    $filters = array();
    
  public function filter(Image $image){
    foreach($this->filters as $filter){
      $image->setResource(
        $filter->filter($image)->getResource()
      );
    }
    return $image;
  }
  
  public function addFilter(IFilter $filter){
    array_push($this->filters, $filter);
  }
}

class GrayScaleFilter implements IFilter
{
  public function filter(Image $image){
    $im = $image->getResource();
    imagefilter($im, IMG_FILTER_GRAYSCALE);
    $image->setResource($im);
    return $image;
  }
}

class ResizeFilter implements IFilter
{
  protected
    $percent;
    
  public function __construct($percent){
    $this->percent = $percent / 100;
  }
  
  public function filter(Image $image){
    
    $newWidth = $image->getWidth() * $this->percent;
    $newHeight = $image->getHeight() * $this->percent;
    
    $new_im = imagecreatetruecolor($newWidth, $newHeight);
    $old_im = $image->getResource();
    
    imagecopyresampled($new_im, $old_im, 0, 0, 0, 0, $newWidth, $newHeight, $image->getWidth(), $image->getHeight());
    
    $image->setResource($new_im);
    
    return $image;
  }
}
?>

Thoughts?