Image resize in PHP - php

I am very new to Resize image in php.Basically i wanted to make thumbnail image using uploaded image. i have used below code but its not working, can anybody help me?..
Thanks in Advance...
$source_image = $path.$row->photosfolder;
$size = getimagesize($source_image);
$w = $size[0];
$h = $size[1];
$simg = imagecreatefromjpeg($source_image);
$dimg = imagecreatetruecolor(150, 225);
$wm = $w / 150;
$hm = $h / 225;
$h_height = 225 / 2;
$w_height = 150 / 2;
if ($w > $h) {
$temp = imagecopyresampled($dimg, $simg, 0, 0, 0, 0, 150, 225, $w, $h);
}
elseif (($w < $h) || ($w == $h)) {
$temp = imagecopyresampled($dimg, $simg, 0, 0, 0, 0, 150, 225, $w, $h);
}
else {
$temp = imagecopyresampled($dimg, $simg, 0, 0, 0, 0, 150, 225, $w, $h);
}
$thumb_image = imagejpeg($dimg, $simg, 100);

check timthumb.php is easy to use and you can find the code full educational

If you want to resize an image, you should do it on client side because PHP image manipulation takes a lot of memory and CPU time, and it doesn't have to be done on server side (there are no access to db, no access to session, etc).
If you still want to do it on PHP, you can use that functions to get the right sizes :
list($realW, $realH) = getimagesize($source_image);
$realR = $realW / $realH;
$thumbR = $thumbW / $thumbH;
// If you want your resize image to fit inside the max thumb size :
if($realR > $thumbR) // Real image if flatter than thumb
{
$newW = $thumbW;
$newH = $newW / $realR;
}
else
{
$newH = $thumbH;
$newW = $newH * $realR;
}
// Or if you want your resize image to be as small as possible but
// not smaller than your thumb. This can be helpful in some cases.
if($realR < $thumbR)
{
// Same code
}
And then use copy resampled as you did (read php manual if you can't get it to work, there are examples below the synopsis of the function).
If you want to resize an image using javascript, you can use the <canvas> :
var canvas = document.createElement('canvas');
var image = document.getElementById('image');
var context = canvas.getContext('2d');
context.save();
context.drawImage(image, /* Here you put the right values using the algorithms above */);
context.restore();
var thumb = document.createElement('image');
thumb.src = canvas.toDataUrl();
Or something like that. You may change a few things depending on your specific case.

Please try with below code, It will resize image and create new thumbnail. New size is defined 100 X 100. This example will also keep aspected ratio of image.
Note:
1.Image path will be directory path if want to set full path.
2. In example we consider for jpg file, you can use for PGN & GIF file with imagecreatefrompng, imagecreatefromgif.
3.This will create PNG file.
$_imagePath = 'somefile.jpg';
$im = imagecreatefromjpeg($_imagePath);
imagealphablending($im, true);
$_orgWidth = imagesx($im);
$_orgHeight = imagesy($im);
$_newWidth = 100;
$_newHeight = 100;
$_finalHeight = $_orgHeight * ( $_newWidth/ $_orgWidth);
if($_finalHeight > $_newHeight){
$_newWidth = $_orgWidth * ($_newHeight / $_orgHeight);
}else{
$_newHeight = $_finalHeight ;
}
$_thumb = imagecreatetruecolor($_newWidth, $_newHeight);
imagealphablending($_thumb, true);
imagesavealpha($_thumb, true);
imagecopyresampled($_thumb, $im, 0, 0, 0, 0, $_newWidth, $_newHeight, $_orgWidth , $_orgHeight );
imagepng($_thumb, 'newname.png');
imagedestroy($_thumb);

Related

how to cut a picture (not cropping) with php

I want to cut out part of the photo without stretch it.
Something like the photo I posted, cut out the red part and get photo number 2
With a width of 150px and height of 100px and cuting from top left of photo
enter image description here
I tried to do it with this code but it didn't work.
This codes separates part of the image, but does not do so from the top left of the image.
function resizejpeg($dir, $newdir, $img, $max_w, $max_h, $th_w, $th_h)
{
// set destination directory
if (!$newdir) $newdir = $dir;
// get original images width and height
list($or_w, $or_h, $or_t) = getimagesize($dir.$img);
// make sure image is a jpeg
if ($or_t == 2) {
// obtain the image's ratio
$ratio = ($or_h / $or_w);
// original image
$or_image = imagecreatefromjpeg($dir.$img);
// resize image?
if ($or_w > $max_w || $or_h > $max_h) {
// resize by height, then width (height dominant)
if ($max_h < $max_w) {
$rs_h = $max_h;
$rs_w = $rs_h / $ratio;
}
// resize by width, then height (width dominant)
else {
$rs_w = $max_w;
$rs_h = $ratio * $rs_w;
}
// copy old image to new image
$rs_image = imagecreatetruecolor($rs_w, $rs_h);
imagecopyresampled($rs_image, $or_image, 0, 0, 0, 0, $rs_w, $rs_h, $or_w, $or_h);
}
// image requires no resizing
else {
$rs_w = $or_w;
$rs_h = $or_h;
$rs_image = $or_image;
}
// generate resized image
imagejpeg($rs_image, $newdir.$img, 100);
$th_image = imagecreatetruecolor($th_w, $th_h);
// cut out a rectangle from the resized image and store in thumbnail
$new_w = (($rs_w / 2) - ($th_w / 2));
$new_h = (($rs_h / 2) - ($th_h / 2));
imagecopyresized($th_image, $rs_image, 0, 0, $new_w, $new_h, $rs_w, $rs_h, $rs_w, $rs_h);
// generate thumbnail
imagejpeg($th_image, $newdir.'thumb_'.$img, 100);
return true;
}
// Image type was not jpeg!
else {
return false;
}
}
$dir = './';
$img = '1.jpg';
$size = getimagesize($img);
$width = $size[0];
$height = $size[1];
resizejpeg($dir, '', $img, $width, $height, 150, 100);
I didn't understand correctly what you mean, but based on your description you are trying to get the image no 2 which means you are trying to crop an image. If that your mean, maybe this code will help
function crop($image_path, $output_path, $x, $y, $width, $height) {
// load image
$image = imagecreatefromjpeg($image_path);
// crop the image
$cropped_image = imagecrop($image, [
'x' => $x,
'y' => $y,
'width' => $width,
'height' => $height
]
);
// save it
imagejpeg($cropped_image, $output_path);
}
you can use it like this
// input image path
$image = "img.jpg";
// output image path
$output = "crop_img.jpg";
// crop it from (0,0)
crop($image, $output, 0, 0, 150, 100);

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

php imagecopyresampled poor quality

I have a php script which saves the original image, then resizes it - one thumbnail and one larger image for web viewing. This works well except with some images the quality is terrible. It seems to be saved with a very low colour pallet. You can see the result at http://kalpaitch.com/index.php?filter=white - click on the first thumbnail with the title 'white white white'
Below is the code used for the image resampling:
function resizeImg($name, $extension, $size1, $size2) {
if (preg_match('/jpg|jpeg|JPG|JPEG/',$extension)){
$image = imagecreatefromjpeg($name);
}
if (preg_match('/gif|GIF/',$extension)){
$image = imagecreatefromgif($name);
}
$old_width = imageSX($image);
$old_height = imageSY($image);
$old_aspect_ratio = $old_width/$old_height;
if($size2 == 0){
$new_aspect_ratio = $old_aspect_ratio;
if($old_width > $old_height){
$new_width = $size1;
$new_height = $new_width / $old_aspect_ratio;
} else {
$new_height = $size1;
$new_width = $new_height * $old_aspect_ratio;
}
} elseif($size2 > 0){
$new_aspect_ratio = $size1/$size2;
//for landscape potographs
if($old_aspect_ratio >= $new_aspect_ratio) {
$x1 = round(($old_width - ($old_width * ($new_aspect_ratio/$old_aspect_ratio)))/2);
$old_width = round($old_width * ($new_aspect_ratio/$old_aspect_ratio));
$y1 = 0;
$new_width = $size1;
$new_height = $size2;
//for portrait photographs
} else{
$x1 = 0;
$y1 = 0;
$old_height = round($old_width/$new_aspect_ratio);
$new_width = $size1;
$new_height = $size2;
}
}
$new_image = imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($new_image, $image, 0, 0, $x1, $y1, $new_width, $new_height, $old_width, $old_height);
return $new_image;
Many Thanks
P.S.
[photos removed from server]
And here is the rest of the upload code:
// Move the original to the right place
$result = #move_uploaded_file($image['tmp_name'], $origlocation);
// Resize the image and save the thumbnail
$new_image = resizeImg($origlocation, $extension, 500, 0);
if (preg_match("/gif/",$extension)){
imagegif($new_image, $normallocation);
} else {
imagejpeg($new_image, $normallocation);
}
// Resize the image and save the thumbnail
$new_image = resizeImg($origlocation, $extension, 190, 120);
if (preg_match("/gif/",$extension)){
imagegif($new_image, $thumblocation);
} else {
imagejpeg($new_image, $thumblocation);
}
The loss in quality is down not to imagecopyresampled(), but to the JPEG compression. Unfortunately, GD's compression algorithms are no match to Photoshop's - in fact, very few are. But you can improve the result: GD's default JPG compression level is 75 of 100.
You can raise the quality using the third parameter to imagejpeg() (which I assume you are using for the final output):
imagejpeg ( $new_image, null, 99);
Play around in the 90-100 range. The image will become larger in file size than the original - that is going to be the price you pay. But it should be possible to achieve comparable quality.
Alternatively, as John Himmelman already says in the comments, try using imagepng() for better quality - also at the price of a notably larger file size, of course.
well, php.net documentation says you should have a imagecreatetruecolor() image for your dest_image if you want to avoid using only a 255 color palette but you already do that.
I guess an alternative would be to use an external tools such as imagemagick with a system() call.
The quick an dirty trick is to make the thumbnails 1000 x 1000 pixels (or more) on imagecopyresized() then set the JPEG quality to 20 or less on imagejpeg($img, $savePath, 20);. The output will usually be smaller than 100 kb.
Let the client CSS do the resizing and the pictures will be fast to load and look flawless in modern browsers when scaled to thumbnail size.
function img_resize( $tmpname, $size, $save_dir, $save_name, $maxisheight = 0 )
{
$save_dir .= ( substr($save_dir,-1) != "/") ? "/" : "";
$gis = getimagesize($tmpname);
$type = $gis[2];
switch($type)
{
case "1": $imorig = imagecreatefromgif($tmpname); break;
case "2": $imorig = imagecreatefromjpeg($tmpname);break;
case "3": $imorig = imagecreatefrompng($tmpname); break;
default: $imorig = imagecreatefromjpeg($tmpname);
}
$x = imagesx($imorig);
$y = imagesy($imorig);
$woh = (!$maxisheight)? $gis[0] : $gis[1] ;
if($woh <= $size)
{
$aw = $x;
$ah = $y;
}
else
{
if(!$maxisheight)
{
$aw = $size;
$ah = $size * $y / $x;
}
else
{
$aw = $size * $x / $y;
$ah = $size;
}
}
$im = imagecreatetruecolor($aw,$ah);
if (imagecopyresampled($im,$imorig , 0,0,0,0,$aw,$ah,$x,$y))
if (imagejpeg($im, $save_dir.$save_name))
return true;
else
return false;
}

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