PHP GD crop & scale image - php

I'm using jQuery's imgAreaSelect plugin in order to crop an image and save the thumbnail to use in cases where, for example, the ratio changes. Unfortunelly the results are far from what I would expect, and I can't get it right. The image gets resized as a whole instead of being cropped.
Here's the test example :
<?php
/***
*
* $_GET returned values
*
* x1 = 0
* x2 = 400
* y1 = 66
* y2 = 258
* w = 400
* h = 192
* folder = widethumb
* filename = IMG_4591.jpg
* scale = 48
*
* Original image properties
*
* width = 600px
* height = 900px
*
***/
define('DOCROOT', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR);
extract($_GET);
$fn = $filename;
$filename = DOCROOT.$filename;
list($width, $height) = getimagesize($filename);
$src = imagecreatefromjpeg($filename);
$dst = imagecreatetruecolor($w, $h);
imagecopyresampled($dst, $src, 0, 0, (int) $x1, (int) $y1, (int) $w, (int) $h, $width, $height);
header('Content-Type: image/jpeg');
imagejpeg($dst);
What am I mising here?
Cheers!

From PHP Documentation:
bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
imagecopyresampled() copies a rectangular portion of one image to another image, smoothly interpolating pixel values so that, in particular, reducing the size of an image still retains a great deal of clarity.
In other words, imagecopyresampled() will take an rectangular area from src_image of width src_w and height src_h at position (src_x,src_y) and place it in a rectangular area of dst_image of width dst_w and height dst_h at position (dst_x,dst_y).
So to get the result you are looking for, you need to avoid scaling. for that use:
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
// this can also be done but is less efficient (over 10 times slower)
imagecopyresampled($dst, $src, 0, 0, (int) $x1, (int) $y1, $w, $h, $w, $h);
Here we are are taking the same sized rectangle from source as we are putting it into destination image.
I have just tested it and it works just fine.
Update:
I have just tried again on my test server and it is working fine. I'm using following code:
$filename = "test.jpg";
extract($_GET);
$src = imagecreatefromjpeg($filename);
$dst = imagecreatetruecolor($w, $h);
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
// this is over 10 times slower, as we are only cropping we should use imagecopy
//imagecopyresampled($dst, $src, 0, 0, $x1, $y1, $w, $h, $w, $h);
header('Content-Type: image/jpeg');
imagejpeg($dst);
And I'm calling it like this:
http://localserver/test/gd_crop.php?x1=906&y1=267&w=501&h=355
Performance Update
As we are not resizing we can simply use imagecopy. Performance of 3 functions as i have measured is given below.
imagecopyresampled 69ms
imagecopyresized 5.5ms
imagecopy 4.5ms
So there is an order of 10 speed difference between resampled and the two other functions.
I have finally come up with following line in place of imagecopyresampled function, try it, I have also updated the above code listing:
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);

Use the WideImage library instead.
This is my own cropping function:
function createThumbnail($file, $cropX, $cropY, $cropWidth, $cropHeight, $desiredWidth, $desiredHeight, $shrink = false)
{
if(file_exists(MPS_ROOT_PATH . "$file") && $cropWidth && $cropHeight)
{
$source_path = MPS_ROOT_PATH . $file;
list( $source_width, $source_height, $source_type ) = getimagesize( $source_path );
switch ( $source_type )
{
case IMAGETYPE_GIF:
$source_gdim = imagecreatefromgif( $source_path );
break;
case IMAGETYPE_JPEG:
$source_gdim = imagecreatefromjpeg( $source_path );
break;
case IMAGETYPE_PNG:
$source_gdim = imagecreatefrompng( $source_path );
break;
default:
return false;
}
if(!$desiredWidth)
{
// Desired width not set, computing new width based on original
// image's aspect ratio...
$desiredWidth = $cropWidth * ($desiredHeight / $cropHeight);
}
if(!$desiredHeight)
{
// Desired height not set, computing new height based on original
// image's aspect ratio
$desiredHeight = $cropHeight * ($desiredWidth / $cropWidth);
}
if(!$desiredWidth || !$desiredHeight)
{
// Desired height or width not set.
// Halting image processing and returning file
return $file;
}
$source_aspect_ratio = $cropWidth / $cropHeight;
$desired_aspect_ratio = $desiredWidth / $desiredHeight;
if($shrink)
{
// Shrink to fit flag set. Inverting computations to make image fit
// within the desired dimensions...
if($source_aspect_ratio > $desired_aspect_ratio)
{
// Source image is wider than desired aspect ratio,
// setting thumbnail width to the desired width and the height
// will be computed based on the original image's aspect ratio
$temp_width = $desiredWidth;
$temp_height = (int) ($desiredWidth / $source_aspect_ratio);
}
else
{
// Source image is taller than desired aspect ratio,
// setting thumbnail height to the desired height and the width
// will be computed based on the original image's aspect ratio
$temp_height = $desiredHeight;
$temp_width = (int) ($desiredHeight * $source_aspect_ratio);
}
}
// shrink to fit not set
else
{
if($source_aspect_ratio > $desired_aspect_ratio)
{
// Source image is wider than desired aspect ratio,
// setting thumbnail height to the desired height to fill the
// desired aspect ratio and the width will be computed based on
// the original image's aspect ratio
$temp_height = $desiredHeight;
$temp_width = (int) ($desiredHeight * $source_aspect_ratio);
}
else
{
// Source image is taller than desired aspect ratio,
// setting thumbnail width to the desired width to fill the
// desired aspect ratio and the width will be computed based on
// the original image's aspect ratio");
$temp_width = $desiredWidth;
$temp_height = (int) ($desiredWidth / $source_aspect_ratio);
}
}
$temp_gdim = imagecreatetruecolor($temp_width, $temp_height);
// Copying a $cropWidth x $cropHeight image from the source
// file at ($cropX, $cropY) and resampling it to fit the temporary
// $temp_width x $temp_height thumbnail at (0, 0)
imagecopyresampled(
$temp_gdim,
$source_gdim,
0, 0,
$cropX, $cropY,
$temp_width, $temp_height,
$cropWidth, $cropHeight
);
$x0 = ($desiredWidth - $temp_width) / 2;
$y0 = ($desiredHeight - $temp_height) / 2;
// Positioning the temporary $temp_width x $temp_height thumbnail in
// the center of the final $desiredWidth x $desiredHeight thumbnail...
// Creating final thumbnail canvas at $desiredWidth x $desiredHeight
$desired_gdim = imagecreatetruecolor($desiredWidth, $desiredHeight);
$white = imagecolorallocate($desired_gdim, 255, 255, 255);
imagefill($desired_gdim, 0, 0, $white);
// Filling final thumbnail canvas with white
// Copying a $temp_width x $temp_height image from the temporary
// thumbnail at (0, 0) and placing it in the final
// thumbnail at ($x0, $y0)
imagecopy(
$desired_gdim,
$temp_gdim,
$x0, $y0,
0, 0,
$temp_width, $temp_height
);
$pathInfo = pathinfo($file);
$thumbFile = "images/thumbs/thumb_" . basename($pathInfo["filename"]) . ".jpg";
if(imagejpeg($desired_gdim, MPS_ROOT_PATH . $thumbFile, 80))
{
return $thumbFile;
}
else
{
return 1;
}
}
else
{
echo "Image File Does not exist or Invalid crop parameters!";
return false;
}
}

Why don't you look into using imagemagik; it's great for image manipulation and cropping is just a simple case of using cropImage($width, $height, $x, $y);

Here's a function that you can pass the destination dimension to and will scale and crop from the center, maintain aspect ratio, and will scale up. This is easy to implement with the picture element for responsive design. If you change your destination dimensions, just delete the outputted files and this will recreate the images in their absence.
<?php
function scaleCrop($src, $dest, $destW, $destH, $anchor){
if(!file_exists($dest) && is_file($src) && is_readable($src)){
$srcSize = getimagesize($src);
$srcW = $srcSize[0];
$srcH = $srcSize[1];
$srcRatio = $srcW / $srcH;
$destRatio = $destW / $destH;
$img = (imagecreatefromjpeg($src));
$imgNew = imagecreatetruecolor($destW, $destH);
if ($srcRatio < $destRatio){
$scale = $srcW / $destW;
}
elseif($srcRatio >= $destRatio){
$scale = $srcH / $destH;
}
$srcX = ($srcW - ($destW * $scale)) / 2;
if($anchor = 'middle'){
$srcY = ($srcH - ($destH * $scale)) / 2;
}
elseif($anchor = 'top'){
$srcY = 0;
}
elseif($anchor = 'bottom'){
$srcY = $srcH - ($destH * $scale);
}
if($srcX < 0){$srcX = 0;};
if($srcY < 0){$srcY = 0;};
imagecopyresampled($imgNew, $img, 0, 0, $srcX, $srcY, $destW, $destH, $destW * $scale, $destH * $scale);
imagejpeg($imgNew, $dest, 70);
imagedestroy($img);
imagedestroy($imgNew);
}
return $dest;
}
?>
<img src="<?php echo scaleCrop('srcfolder/srcfile.jpg', 'destfolder/destfile.jpg', 320, 240, 'top'); ?>">

Related

Issue with imagecopy resized PHP

I'm trying to make a web app which has an admin site where you can upload an image. I'm already using imagecopy() to make a square photo. But when the image is too big I'm trying to resize with imagecopyresized(). I've already used this code:
$file = $_FILES['img']['tmp_name'];
$filename = $_FILES['img']['name'];
$size = 400;
$destino = imagecreatetruecolor($size, $size);
list($width, $height) = getimagesize($file);
$correction = $size / 2;
$widths = $width / 2 - $correction;
$heights = $height / 2 - $correction;
$origen = imagecreatefromjpeg($file);
$overflow = $size + 200;
if($width > $overflow){
$modified = $origen;
$ratio = $width / $height;
$growth = $width / $overflow;
$final = $overflow / $growth;
if($ratio > 1){
$newwidth = $final * $ratio;
}else{
$newwidth = $final / $ratio;
}
imagecopyresized($origen, $modified, 0, 0, 0, 0, $final, $newwidth, $width, $height);
}
imagecopy($destino, $origen, 0, 0, $widths, $heights, $size, $size);
The issue here is that there's no modification to the image that is bigger than $overflow.
$ratio is to keep the original dimensions of the photos and prevent deform.
$growth is an index that while bigger the image is, the smallest it will be copied.
$final is the final width taking the growth index as a count.
You've made some incorrect assumptions about how PHP handles resources and how the GD functions work.
$modified = $origen;
The above line does not give you two separate image resources; it gives you two variables pointing to the same image resource in memory. This means any operation on one will be reflected in the other.
This causes you to make two mistakes with the following line:
imagecopyresized($origen, $modified, 0, 0, 0, 0, $final, $newwidth, $width, $height);
This function doesn't resize the destination image ($origen) or the source image ($modified); it resizes the part of the image it copies from the source image (i.e., the specified part of $modified in your code).
Because $origen and $modified point to the same resource the function pastes the resized copy of the image on top of itself, like this:
Lastly you call:
imagecopy($destino, $origen, 0, 0, $widths, $heights, $size, $size);
A problem here is that $widths and $heights are calculated before the $origen resize, but in effect the problem is hidden because (as explained above) $origen isn't resized!
The result of all the above is to give you a square 'cut' from the middle of the original image, like this:
Here is how I would resize the input image to fit within 400x400px and centre it in the output:
$file = $_FILES['img']['tmp_name'];
$maxW = $maxH = 400;
list($srcW, $srcH) = getimagesize($file);
$ratio = $srcW / $srcH;
$src = imagecreatefromjpeg($file);
$dest = imagecreatetruecolor($maxW, $maxH);
if ($ratio > 1) {
// landscape.
$destH = ($maxH / $ratio);
imagecopyresized($dest, $src, 0, ($maxH / 2) - ($destH / 2), 0, 0, $maxW, $destH, $srcW, $srcH);
} else {
// portrait (or square).
$destW = ($maxW * $ratio);
imagecopyresized($dest, $src, ($maxW / 2) - ($destW / 2), 0, 0, 0, $destW, $maxH, $srcW, $srcH);
}
// now do whatever you want with $dest...
Note that this will result in black bars on the top/bottom (of a landscape image) or left/right (of a portrait image) of the output. You can just fill $dest with a colour, or transparency, before the imagecopyresized call to change this.

Creating thumbnail and resizing problems

I'm trying to create thumbnail and resize image at the same time, so to be more clear here is the image that i'm trying to crop:
And i would like to cut out that red area.
Now my problem is that i'm resizing my image with html before croping so when i submit data to php i get incorrect values, like y = 100 when realy it could be y = 200 so i need to find a way to calculate my values.
I am using imagecopyresampled, maybe there is something better then this command?
Also my closest soliution was this:
imagecopyresampled(
$thumb, //Destination image link resource.
$src, //Source image link resource.
0, //x-coordinate of destination point.
0, //y-coordinate of destination point.
0, //x-coordinate of source point.
0, //y-coordinate of source point.
120, //Destination width.
160, //Destination height.
$image_width/2, //Source width.
$image_height/2 //Source height.
);
In this case it would cut out left corner but size would be not the same as my red box.
So i guess i need to get source width and source height right and everything else should fit perfectly, anyways i hope i make any sense here :)
EDIT Sorry i forgot to mention, $image_width and $image_height is the original image size
EDIT 2 To be more clear this is what i get when i resize with this code
$dimensions = getimagesize('testas.jpg');
$img = imagecreatetruecolor(120, 160);
$src = imagecreatefromjpeg('testas.jpg');
imagecopyresampled($img, $src, 0, 0, 0, 0, 120, 160, $dimensions[0]/2, $dimensions[1]/2);
imagejpeg($img, 'test.jpg');
Resized image size is correct, but as you can it doesn't look right.
I use something like this to scale images:
public static function scaleProportional($img_w,$img_h,$max=50)
{
$w = 0;
$h = 0;
$img_w > $img_h ? $w = $img_w / $img_h : $w = 1;
$img_h > $img_w ? $h = $img_h / $img_w : $h = 1;
$ws = $w > $h ? $ws = ($w / $w) * $max : $ws = (1 / $h) * $max;
$hs = $h > $w ? $hs = ($h / $h) * $max : $hs = (1 / $w) * $max;
return array(
'width'=>$ws,
'height'=>$hs
);
}
usage:
$getScale = Common::scaleProportional($prevWidth,$prevHeight,$scaleArray[$i][1]);
$targ_w = $getScale['width'];
$targ_h = $getScale['height'];
$jpeg_quality = 100;
$src = $prevdest;
$img_r = imagecreatefromjpeg($src);
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
//imagecopyresampled(dest_img,src_img,dst_x,dst_y,src_x,src_y,dst_w,dst_h,src_w,src_h);
imagecopyresampled($dst_r,$img_r,0,0,0,0,$targ_w,$targ_h,$prevWidth,$prevHeight);
imagejpeg($dst_r, 'assets/images/'.$scaleArray[$i][0].'/'.$filename, $jpeg_quality);
$complete[] = $scaleArray[$i][0];
When you say 'resizing with HTML', do you mean specifying the size using the width and height attributes of the img element? If so, this won't affect the dimensions of the file on the server, and you can still get those using getimagesize.
Something like this will return the source width and height of the image:
function get_source_size($the_file_path)
{
$imagesize = getimagesize($the_file_path);
return array('width' => $imagesize[0], 'height' => $imagesize[1]);
}
So after some time i was able to do it with my friend help, this is the script i used, maybe some one will need it in the future :)
private function crop($user, $post){
//get original image size
$dimensions = getimagesize($post['image_src']);
//get crop box dimensions
$width = $post['w'] * ($dimensions[0] / $post['img_width']);
$height = $post['h'] * ($dimensions[1] / $post['img_height']);
//get crop box offset
$y = $post['y'] * ($dimensions[1] / $post['img_height']);
$x = $post['x'] * ($dimensions[0] / $post['img_width']);
//create image 120x160
$img = imagecreatetruecolor(120, 160);
$src = imagecreatefromjpeg($post['image_src']);
imagecopyresampled($img, $src, 0, 0, $x, $y, 120, 160, $width, $height);
//and save the image
return imagejpeg($img, 'uploads/avatars/'.$user->id.'/small/'.$post['image_name'].".jpg" , 100);
}

Resize an image and fill gaps of proportions with a color

I am uploading logos to my system, and they need to fix in a 60x60 pixel box. I have all the code to resize it proportionately, and that's not a problem.
My 454x292px image becomes 60x38. The thing is, I need the picture to be 60x60, meaning I want to pad the top and bottom with white each (I can fill the rectangle with the color).
The theory is I create a white rectangle, 60x60, then I copy the image and resize it to 60x38 and put it in my white rectangle, starting 11px from the top (which adds up to the 22px of total padding that I need.
I would post my code but it's decently long, though I can if requested.
Does anyone know how to do this or can you point me to code/tutorial that does this?
With GD:
$newWidth = 60;
$newHeight = 60;
$img = getimagesize($filename);
$width = $img[0];
$height = $img[1];
$old = imagecreatefromjpeg($filename); // change according to your source type
$new = imagecreatetruecolor($newWidth, $newHeight)
$white = imagecolorallocate($new, 255, 255, 255);
imagefill($new, 0, 0, $white);
if (($width / $height) >= ($newWidth / $newHeight)) {
// by width
$nw = $newWidth;
$nh = $height * ($newWidth / $width);
$nx = 0;
$ny = round(fabs($newHeight - $nh) / 2);
} else {
// by height
$nw = $width * ($newHeight / $height);
$nh = $newHeight;
$nx = round(fabs($newWidth - $nw) / 2);
$ny = 0;
}
imagecopyresized($new, $old, $nx, $ny, 0, 0, $nw, $nh, $width, $height);
// do something with new: like imagepng($new, ...);
imagedestroy($new);
imagedestroy($old);
http://php.net/manual/en/function.imagecopyresampled.php
That's basically the function you want to copy and resize it smoothly.
http://www.php.net/manual/en/function.imagecreatetruecolor.php
With that one you create a new black image.
http://www.php.net/manual/en/function.imagefill.php
That part explains how to fill it white.
The rest follows.

php gd: when i crop images through php some images come out smushed

here is the website im talking about
http://makeupbyarpi.com/portfolio.php
you'll notice some of the images are smushed width-wise.
the code i used is this:
$width="500";
$height="636";
$img_src = $_FILES['galleryimg']['tmp_name'];
$thumb = "../gallery/".rand(0,100000).".jpg";
//Create image stream
$image = imagecreatefromjpeg($img_src);
//Gather and store the width and height
list($image_width, $image_height) = getimagesize($img_src);
//Resample/resize the image
$tmp_img = imagecreatetruecolor($width, $height);
imagecopyresampled($tmp_img, $image, 0, 0, 0, 0, $width, $height, $image_width, $image_height);
//Attempt to save the new thumbnail
if(is_writeable(dirname($thumb))){
imagejpeg($tmp_img, $thumb, 100);
}
//Free memory
imagedestroy($tmp_img);
imagedestroy($image);
the images that get uploaded are huge sometimes 3000px by 2000px and i have php crop it down to 500 x 536 and some landscape based images get smushed. is there a formula i can use to crop it carefully so that the image comes out good?
thanks
You could resize and add a letterbox if required. You simply need to resize the width and then calculate the new height (assuming width to height ratio is same as original) then if the height is not equal to the preferred height you need to draw a black rectangle (cover background) and then centre the image.
You could also do a pillarbox, but then you do the exact same as above except that width becomes height and height becomes width.
Edit: Actually, you resize the one that is the biggest, if width is bigger, you resize that and if height is bigger then you resize that. And depending on which one you resize, your script should either letterbox or pillarbox.
EDIT 2:
<?php
// Define image to resize
$img_src = $_FILES['galleryimg']['tmp_name'];
$thumb = "../gallery/" . rand(0,100000) . ".jpg";
// Define resize width and height
$width = 500;
$height = 636;
// Open image
$img = imagecreatefromjpeg($img_src);
// Store image width and height
list($img_width, $img_height) = getimagesize($img_src);
// Create the new image
$new_img = imagecreatetruecolor($width, $height);
// Calculate stuff and resize image accordingly
if (($width/$img_width) < ($height/$img_height)) {
$new_width = $width;
$new_height = ($width/$img_width) * $img_height;
$new_x = 0;
$new_y = ($height - $new_height) / 2;
} else {
$new_width = ($height/$img_height) * $img_width;
$new_height = $height;
$new_x = ($width - $new_width) / 2;
$new_y = 0;
}
imagecopyresampled($new_img, $img, $new_x, $new_y, 0, 0, $new_width, $new_height, $img_width, $img_height);
// Save thumbnail
if (is_writeable(dirname($thumb))) {
imagejpeg($new_img, $thumb, 100);
}
// Free up resources
imagedestroy($new_img);
imagedestroy($img);
?>
Sorry it took a while, I ran across a small bug in the calculation part which I was unable to fix for like 10 minutes =/ This should work.

Cropping image in PHP

I'd like crop an image in PHP and save the file. I know your supposed to use the GD library but i'm not sure how. Any ideas?
Thanks
You could use imagecopy to crop a required part of an image. The command goes like this:
imagecopy (
resource $dst_im - the image object ,
resource $src_im - destination image ,
int $dst_x - x coordinate in the destination image (use 0) ,
int $dst_y - y coordinate in the destination image (use 0) ,
int $src_x - x coordinate in the source image you want to crop ,
int $src_y - y coordinate in the source image you want to crop ,
int $src_w - crop width ,
int $src_h - crop height
)
Code from PHP.net - a 80x40 px image is cropped from a source image
<?php
// Create image instances
$src = imagecreatefromgif('php.gif');
$dest = imagecreatetruecolor(80, 40);
// Copy
imagecopy($dest, $src, 0, 0, 20, 13, 80, 40);
// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);
imagedestroy($dest);
imagedestroy($src);
?>
This function will crop image maintaining image aspect ratio :)
function resize_image_crop($image, $width, $height)
{
$w = #imagesx($image); //current width
$h = #imagesy($image); //current height
if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
if (($w == $width) && ($h == $height)) { return $image; } //no resizing needed
$ratio = $width / $w; //try max width first...
$new_w = $width;
$new_h = $h * $ratio;
if ($new_h < $height) { //if that created an image smaller than what we wanted, try the other way
$ratio = $height / $h;
$new_h = $height;
$new_w = $w * $ratio;
}
$image2 = imagecreatetruecolor ($new_w, $new_h);
imagecopyresampled($image2,$image, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
if (($new_h != $height) || ($new_w != $width)) { //check to see if cropping needs to happen
$image3 = imagecreatetruecolor ($width, $height);
if ($new_h > $height) { //crop vertically
$extra = $new_h - $height;
$x = 0; //source x
$y = round($extra / 2); //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
} else {
$extra = $new_w - $width;
$x = round($extra / 2); //source x
$y = 0; //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
}
imagedestroy($image2);
return $image3;
} else {
return $image2;
}
}
To crop an image using GD you need to use a combination of GD methods, and if you look at "Example #1" on PHP's documentation of the imagecopyresampled method, it shows you how to crop and output an image, you would just need to add some code to that to capture and write the output to a file...
http://us2.php.net/manual/en/function.imagecopyresampled.php
There are also other options, including Image Magick which, if installed on your server, can be accessed directly using PHP's exec method (or similar) or you can install the PHP Imagick extension, which yields higher quality images and, in my opinion, is a little more intuitive and flexible to work with.
Finally, I've used the open source PHPThumb class library, which has a pretty simple interface and can work with multiple options depending on what's on your server, including ImageMagick and GD.
I use this script in some projects and it's pretty easy to use:
http://shiftingpixel.com/2008/03/03/smart-image-resizer/
The script requires PHP 5.1.0 (which is out since 2005-11-24 - time to upgrade if not yet at this version) and GD (which is rarely missing from good Web hosts).
Here is an example of it's use in your HTML:
<img src="/image.php/coffee-bean.jpg?width=200&height=200&image=/wp-content/uploads/2008/03/coffee-bean.jpg" alt="Coffee Bean" />
I just created this function and it works for my needs, creating a centered and cropped thumbnail image. It is streamlined and doesn't require multiple imagecopy calls like shown in webGautam's answer.
Provide the image path, the final width and height, and optionally the quality of the image. I made this for creating thumbnails, so all images are saved as JPGs, you can edit it to accommodate other image types if you require them. The main point here is the math and method of using imagecopyresampled to produce a thumbnail. Images are saved using the same name, plus the image size.
function resize_crop_image($image_path, $end_width, $end_height, $quality = '') {
if ($end_width < 1) $end_width = 100;
if ($end_height < 1) $end_height = 100;
if ($quality < 1 || $quality > 100) $quality = 60;
$image = false;
$dot = strrpos($image_path,'.');
$file = substr($image_path,0,$dot).'-'.$end_width.'x'.$end_height.'.jpg';
$ext = substr($image_path,$dot+1);
if ($ext == 'jpg' || $ext == 'jpeg') $image = #imagecreatefromjpeg($image_path);
elseif($ext == 'gif') $image = #imagecreatefromgif($image_path);
elseif($ext == 'png') $image = #imagecreatefrompng($image_path);
if ($image) {
$width = imagesx($image);
$height = imagesy($image);
$scale = max($end_width/$width, $end_height/$height);
$new_width = floor($scale*$width);
$new_height = floor($scale*$height);
$x = ($new_width != $end_width ? ($width - $end_width) / 2 : 0);
$y = ($new_height != $end_height ? ($height - $end_height) / 2 : 0);
$new_image = #imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($new_image,$image,0,0,$x,$y,$new_width,$new_height,$width - $x,$height - $y);
imagedestroy($image);
imagejpeg($new_image,$file,$quality);
imagedestroy($new_image);
return $file;
}
return false;
}
You can use below method to crop image,
/*parameters are
$image =source image name
$width = target width
$height = height of image
$scale = scale of image*/
function resizeImage($image,$width,$height,$scale) {
//generate new image height and width of source image
$newImageWidth = ceil($width * $scale);
$newImageHeight = ceil($height * $scale);
//Create a new true color image
$newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
//Create a new image from file
$source = imagecreatefromjpeg($image);
//Copy and resize part of an image with resampling
imagecopyresampled($newImage,$source,0,0,0,0,$newImageWidth,$newImageHeight,$width,$height);
//Output image to file
imagejpeg($newImage,$image,90);
//set rights on image file
chmod($image, 0777);
//return crop image
return $image;
}

Categories