Copy and resize image with php GD library - php

I want to copy, resize and (if it is not too hard) crop an image.
For example: I have an image with the dimensions 1200 height X 2300 width. I want to make an 100x100 pixels thumbnail of it, and in this case, because the height is less than the width the height should be 100% visible on the new image, and the width should keep the aspect ratio of the image. Here is an example image.
Additional details:
I am using wamp, Ihave enabled Gd 2
I just get broken images when I try rewriting the code from the example on this site.

try this one its from the Resize Images Using PHP and GD Library article
define('THUMBNAIL_IMAGE_MAX_WIDTH', 150);
define('THUMBNAIL_IMAGE_MAX_HEIGHT', 150);
function generate_image_thumbnail($source_image_path, $thumbnail_image_path)
{
list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
switch ($source_image_type) {
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif($source_image_path);
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg($source_image_path);
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng($source_image_path);
break;
}
if ($source_gd_image === false) {
return false;
}
$source_aspect_ratio = $source_image_width / $source_image_height;
$thumbnail_aspect_ratio = THUMBNAIL_IMAGE_MAX_WIDTH / THUMBNAIL_IMAGE_MAX_HEIGHT;
if ($source_image_width <= THUMBNAIL_IMAGE_MAX_WIDTH && $source_image_height <= THUMBNAIL_IMAGE_MAX_HEIGHT) {
$thumbnail_image_width = $source_image_width;
$thumbnail_image_height = $source_image_height;
} elseif ($thumbnail_aspect_ratio > $source_aspect_ratio) {
$thumbnail_image_width = (int) (THUMBNAIL_IMAGE_MAX_HEIGHT * $source_aspect_ratio);
$thumbnail_image_height = THUMBNAIL_IMAGE_MAX_HEIGHT;
} else {
$thumbnail_image_width = THUMBNAIL_IMAGE_MAX_WIDTH;
$thumbnail_image_height = (int) (THUMBNAIL_IMAGE_MAX_WIDTH / $source_aspect_ratio);
}
$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);
imagejpeg($thumbnail_gd_image, $thumbnail_image_path, 90);
imagedestroy($source_gd_image);
imagedestroy($thumbnail_gd_image);
return true;
}
?>

Have you tried to use Timthumb? It's a nice little script that matches your requirements.
If you get corrupted image files something with your GD installation might be wrong, but without seeing any code it's hard to guess. Do you have any other machine (maybe a webhost with LAMP stack) to test your code there?

Related

Dart/Flutter Alternative to PHP's resize_crop_image?

Currently, I am resizing avatars on my server using PHP's resize_crop_image. The code below takes an image, crops and resizes it so that it's exactly 500px X 500px square.
resize_crop_image(500, 500, $filename, $filename);
But I'd like to move this process from the server to the flutter app. Most of the plugins I'm seeing on pub.dev are overkill with the user cropping the image using a crop tool. But I'd like this function to happen automatically the way I currently do it in PHP.
Here's the resize_crop_image code;
function resize_crop_image($max_width, $max_height, $source_file, $dst_dir, $quality = 100){
$imgsize = getimagesize($source_file);
$width = $imgsize[0];
$height = $imgsize[1];
$mime = $imgsize['mime'];
switch($mime){
case 'image/gif':
$image_create = "imagecreatefromgif";
$image = "imagegif";
break;
case 'image/png':
$image_create = "imagecreatefrompng";
$image = "imagepng";
$quality = 10;
break;
case 'image/jpeg':
$image_create = "imagecreatefromjpeg";
$image = "imagejpeg";
$quality = 100;
break;
default:
return false;
break;
}
$dst_img = imagecreatetruecolor($max_width, $max_height);
$src_img = $image_create($source_file);
$width_new = $height * $max_width / $max_height;
$height_new = $width * $max_height / $max_width;
//if the new width is greater than the actual width of the image, then the height is too large and the rest cut off, or vice versa
if($width_new > $width){
//cut point by height
$h_point = (($height - $height_new) / 2);
//copy image
imagecopyresampled($dst_img, $src_img, 0, 0, 0, $h_point, $max_width, $max_height, $width, $height_new);
}else{
//cut point by width
$w_point = (($width - $width_new) / 2);
imagecopyresampled($dst_img, $src_img, 0, 0, $w_point, 0, $max_width, $max_height, $width_new, $height);
}
$image($dst_img, $dst_dir, $quality);
if($dst_img)imagedestroy($dst_img);
if($src_img)imagedestroy($src_img);
}
?>
You could use this library: flutter_native_image for resizing/croping your images.
Important to take a look at the other parameters of this function, you can probably customize the way the image will be cropped.
Something like that:
ImageProperties properties = await FlutterNativeImage.getImageProperties(file.path);
File croppedFile = await FlutterNativeImage.cropImage(file.path, originX, originY, 500, 500);
originX/originY: x/y position for the cut.

Image resize and keep ratio bug

I found and modified a GD image resize and keep ratio script but it's not working as it should.
For example I want to resize a picture to MAXIMUM 200w x 200h keeping ratio. The picture I want to resize is 518w x 691h and the script should resize it to 150w x 200h to keep the aspect ratio but instead it resize it to 200w x 226h. What is the problem?
function resize_image($source_image, $name, $new_width, $new_height, $destination)
{
list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image);
switch($source_image_type)
{
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif($source_image);
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg($source_image);
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng($source_image);
break;
}
$source_aspect_ratio = $source_image_width / $source_image_height;
$thumbnail_aspect_ratio = $new_width / new_height;
if($source_image_width <= $new_width && $source_image_height <= new_height)
{
$thumbnail_image_width = $source_image_width;
$thumbnail_image_height = $source_image_height;
}
elseif ($thumbnail_aspect_ratio > $source_aspect_ratio)
{
$thumbnail_image_width = (int)(new_height * $source_aspect_ratio);
$thumbnail_image_height = new_height;
}
else
{
$thumbnail_image_width = $new_width;
$thumbnail_image_height = (int)($new_width / $source_aspect_ratio);
}
$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
imagealphablending($thumbnail_gd_image, false);
imagesavealpha($thumbnail_gd_image, true);
imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);
$destination = $destination.$name;
switch($source_image_type)
{
case IMAGETYPE_GIF:
imagegif($thumbnail_gd_image, $destination);
break;
case IMAGETYPE_JPEG:
imagejpeg($thumbnail_gd_image, $destination, 100);
break;
case IMAGETYPE_PNG:
imagepng($thumbnail_gd_image, $destination, 9);
break;
}
imagedestroy($source_gd_image);
imagedestroy($thumbnail_gd_image);
}
This section:
elseif ($thumbnail_aspect_ratio > $source_aspect_ratio)
should never execute, since you want to keep the aspect ratios the same. To determine the new width / height, try something like this:
if($width > $MAX_SIZE || $height > $MAX_SIZE) {
$aspect = $width / $height;
if($width > $height) {
$width = $MAX_SIZE;
$height = intval($MAX_SIZE / $aspect);
} else {
$height = $MAX_SIZE;
$width = intval($MAX_SIZE * $aspect);
}
}
Update
All this code is doing is attempting to determine a new width / height based on a restriction $MAX_SIZE, while keeping the aspect ratio the same. It's not going to be perfect because floating point arithemetic is rarely ever so (especially since in this case you can't have 'fractional' pixels, which is why the calculations above use intval). Consider if, for example, before this code is ran $width, $height and $MAX_SIZE are set as follows:
$MAX_SIZE = 100;
$width = 1920;
$height = 1080;
The original aspect ratio is 1.77777777.... After running the snippet above, the width / height will be set to 100 x 56, which is an aspect ratio of 1.7857. Moving the output width/height either up or down by a pixel will not ever get you the exact input aspect ratio, unless you allow pixel values with fractional components.
However you're uploading the file and determining the input file's height / width shouldn't matter, the snippet above is only supposed to get you the resized dimensions as close as possible to the input aspect ratio.

how can I display large image smaller if i don't know its dimensions?

I have the following problem. User can upload image, and I would like to display the image about 5 times smaller, without to cause distortion on the image. That is I would like to avoid. How can I find the width and height of the original image and divide it by 5?
I use php, forgot to mention that detail.
Regards,Zoran
From the sounds of your comments, you are looking for something simpler than the answers you are getting. Have you tried getimagesize? http://php.net/manual/en/function.getimagesize.php
You can do something like this:
$size = getimagesize($filename);
echo $size[0]/5; //width
echo $size[1]/5; //height
This method also has the advantage of not having to rely on an image library like GD or anything.
http://php.net/manual/en/imagick.resizeimage.php
call it with FILTER_GAUSSIAN
<?php
$image = new Imagick( $filename );
$imageprops = $image->getImageGeometry();
if ($imageprops['width'] <= 200 && $imageprops['height'] <= 200) {
// don't upscale
} else {
$image->resizeImage(200,200, imagick::FILTER_GAUSSIAN, 0.9, true);
}
?>
The idea is to blur the image by using gaussian filter and than subsampling it.
After image upload is done, use the following function:
<?php
function generate_image_thumbnail($source_image_path, $thumbnail_image_path){
list($source_image_width, $source_image_height, $source_image_type) = getimagesize($source_image_path);
switch ($source_image_type) {
case IMAGETYPE_GIF:
$source_gd_image = imagecreatefromgif($source_image_path);
break;
case IMAGETYPE_JPEG:
$source_gd_image = imagecreatefromjpeg($source_image_path);
break;
case IMAGETYPE_PNG:
$source_gd_image = imagecreatefrompng($source_image_path);
break;
}
if ($source_gd_image === false) {
return false;
}
$thumbnail_image_width = $source_image_width/5;
$thumbnail_image_height = $source_image_height/5;
$thumbnail_gd_image = imagecreatetruecolor($thumbnail_image_width, $thumbnail_image_height);
imagecopyresampled($thumbnail_gd_image, $source_gd_image, 0, 0, 0, 0, $thumbnail_image_width, $thumbnail_image_height, $source_image_width, $source_image_height);
imagejpeg($thumbnail_gd_image, $thumbnail_image_path, 90);
imagedestroy($source_gd_image);
imagedestroy($thumbnail_gd_image);
return true;
}
?>
Pass right param to the function, it will do the job.
And make sure GD is enabled in your php settings. it uses gd library.

image resize in my wordpress plugin using php

I am trying to resize an image in my wordpress plugin using php, But they don't work. How can I resize image as propotion wise using php?
anyone know if that's possible?
Thanks
You can use wordpress built-in resize function:
<?php image_resize( $file, $max_w, $max_h, $crop, $suffix, $dest_path, $jpeg_quality ); ?>
You can find more details in here: http://codex.wordpress.org/Function_Reference/image_resize
This function takes the imagePath as parameter and the size to which you want it to resize the image.This will resize image with proportion constraints
suppose size = 300
then there will be three scenarios
1) if image's height is greater than width then its height will be 300
2) if width is greater then its width will be 300
3) if image is of ratio 1:1 then both its height and width will be of size 300
function resizeImage($imagePath,$size)
{
$sizeData = getimagesize($imagePath);
$width = $sizeData[0];
$height = $sizeData[1];
# Loading image to memory according to type
switch ( $sizeData[2] ) {
case IMAGETYPE_GIF: $src = imagecreatefromgif($imagePath); break;
case IMAGETYPE_JPEG: $src = imagecreatefromjpeg($imagePath); break;
case IMAGETYPE_PNG: $src = imagecreatefrompng($imagePath); break;
default: return false;
}
if(!$src)
{
return false;
}
if($height >= $width)
{
$newheight = $size;
$newwidth = ($newheight*$width)/$height;
}
else
{
$newwidth = $size;
$newheight = ($height/$width)*$newwidth;
}
$tmp = imagecreatetruecolor($newwidth,$newheight);
imagecopyresampled($tmp,$src,0,0,0,0,$newwidth,$newheight,$width,$height);
# Writing image according to type to the output destination
switch ( $sizeData[2] ) {
case IMAGETYPE_GIF: imagegif($tmp, $imagePath); break;
case IMAGETYPE_JPEG: imagejpeg($tmp, $imagePath, 100); break;
case IMAGETYPE_PNG: imagepng($tmp, $imagePath, 9); break;
default: return false;
}
imagedestroy($src);
imagedestroy($tmp);
return true;
}

How to Improve my php image resizer to support alpha png and transparent GIFs

I use this function to resize images but i end up with ugly creepy image with a black background if it's a transparent GIF or PNG with alpha, however it works perfectly for jpg and normal png.
function cropImage($nw, $nh, $source, $stype, $dest) {
$size = getimagesize($source);
$w = $size[0];
$h = $size[1];
switch($stype) {
case 'gif':
$simg = imagecreatefromgif($source);
break;
case 'jpg':
$simg = imagecreatefromjpeg($source);
break;
case 'png':
$simg = imagecreatefrompng($source);
break;
}
$dimg = imagecreatetruecolor($nw, $nh);
switch ($stype)
{
case "png":
imagealphablending( $dimg, false );
imagesavealpha( $dimg, true );
$transparent = imagecolorallocatealpha($dimg, 255, 255, 255, 127);
imagefilledrectangle($dimg, 0, 0, $nw, $nh, $transparent);
break;
case "gif":
// integer representation of the color black (rgb: 0,0,0)
$background = imagecolorallocate($simg, 0, 0, 0);
// removing the black from the placeholder
imagecolortransparent($simg, $background);
break;
}
$wm = $w/$nw;
$hm = $h/$nh;
$h_height = $nh/2;
$w_height = $nw/2;
if($w> $h) {
$adjusted_width = $w / $hm;
$half_width = $adjusted_width / 2;
$int_width = $half_width - $w_height;
imagecopyresampled($dimg,$simg,-$int_width,0,0,0,$adjusted_width,$nh,$w,$h);
} elseif(($w <$h) || ($w == $h)) {
$adjusted_height = $h / $wm;
$half_height = $adjusted_height / 2;
$int_height = $half_height - $h_height;
imagecopyresampled($dimg,$simg,0,-$int_height,0,0,$nw,$adjusted_height,$w,$h);
} else {
imagecopyresampled($dimg,$simg,0,0,0,0,$nw,$nh,$w,$h);
}
imagejpeg($dimg,$dest,100);
}
Example : cropImage("300","200","original.png","png","new.png");
I use php 5.3.2 and the GD library bundled (2.0.34 compatible)
How to make it support transparency? i've added imagealphablending() and imagesavealpha but it didn't work. Or atlast is there any similar good classes?
Thanks
The ugly black background disappears if you output the image to png. So here are the two alternative solutions, both tested:
If you can store the thumbnail as png, just do it: change imagejpeg($dimg,$dest,100); to imagepng($dimg,$dest);
If it's important to store it as jpeg, remove the lines imagealphablending( $dimg, false ); and imagesavealpha( $dimg, true ); -- the default values of true and false, respectively, will provide the desired effect. Disabling alpha blending only makes sense if the result image also has an alpha channel.
I haven't tested it myself but this was an idea I've had for doing exactly that when working on a project of mine.
First, find a color that isn't used in the image and create a new image with that as the background (really flashy green for example, just like they do with motion capture)
Next, copy your image with transparency over it (I know this works with PHP I used to do this to put borders over images)
Then, use the function imagecolortransparent to define which color in that image is transparent and give it your flashy green color.
I think it would work but I haven't tested it.

Categories