Im trying to create with php a 4:3 image with any image uploaded by user. No matter the image original size, i want to fill the background with a blurred copy of the same image.
This is the code i use (from István Ujj-Mészáros):
function resize($source_image, $destination, $tn_w, $tn_h, $quality = 90) {
$info = getimagesize($source_image);
$imgtype = image_type_to_mime_type($info[2]);
#assuming the mime type is correct
switch ($imgtype) {
case 'image/jpeg':
$source = imagecreatefromjpeg($source_image);
break;
case 'image/gif':
$source = imagecreatefromgif($source_image);
break;
case 'image/png':
$source = imagecreatefrompng($source_image);
break;
default:
die('Invalid image type.');
}
#Figure out the dimensions of the image and the dimensions of the desired thumbnail
$src_w = imagesx($source);
$src_h = imagesy($source);
#Do some math to figure out which way we'll need to crop the image
#to get it proportional to the new size, then crop or adjust as needed
$x_ratio = $tn_w / $src_w;
$y_ratio = $tn_h / $src_h;
if (($src_w <= $tn_w) && ($src_h <= $tn_h)) {
$new_w = $src_w;
$new_h = $src_h;
} elseif (($x_ratio * $src_h) < $tn_h) {
$new_h = ceil($x_ratio * $src_h);
$new_w = $tn_w;
} else {
$new_w = ceil($y_ratio * $src_w);
$new_h = $tn_h;
}
$newpic = imagecreatetruecolor(round($new_w), round($new_h));
imagecopyresampled($newpic, $source, 0, 0, 0, 0, $new_w, $new_h, $src_w, $src_h);
$final = imagecreatetruecolor($tn_w, $tn_h);
// This code fill with green color
//$backgroundColor = imagecolorallocate($final, 0, 255, 0);
//imagefill($final, 0, 0, $backgroundColor);
imagecopy($final, $newpic, (($tn_w - $new_w)/ 2), (($tn_h - $new_h) / 2), 0, 0, $new_w, $new_h);
// This code generates a blurred image
# ****************************************************
//for ($x=1; $x <=2; $x++){
// imagefilter($final, IMG_FILTER_GAUSSIAN_BLUR, 999);
//}
//imagefilter($final, IMG_FILTER_SMOOTH,99);
//imagefilter($final, IMG_FILTER_BRIGHTNESS, 10);
# ****************************************************
if (imagejpeg($final, $destination, $quality)) {
return true;
}
return false;
}
// targetFilePath contains the folder an filename
resize($targetFilePath,$targetFilePath,640,480,90);
The result is like this image: my result until now
What do i need? The result that i hope
Please any idea will be welcome. Thank you in advance!!!
Ok, i did my work and studied more about php image commands. I wrote a solution that works very well.
<?php
$image = "01.jpg";
image_web($image, 700, 525); // I need final images 700x525 (4:3)
echo '<img src="00.jpg"/>';
function image_web($image, $width, $height){ // Get the image source and the final desire dimensions
$info = getimagesize($image);
//$mimetype = $info['mime']; // other way to get mimetype
$mimetype = image_type_to_mime_type($info[2]);
$allowTypes = array('image/jpeg','image/png','image/gif');
if(in_array($mimetype, $allowTypes)){
switch ($mimetype) {
case 'image/jpeg':
$image = imagecreatefromjpeg($image);
break;
case 'image/gif':
$image = imagecreatefromgif($image);
break;
case 'image/png':
$image = imagecreatefrompng($image);
break;
default:
die('Invalid image type.');
}
} else {
echo 'Is not a image';
}
$image2 = $image; // Save a copy to be used for front image
$wor = imagesx($image); // Get original image width
$hor = imagesy($image); // Get original image height
if ($hor >= $wor){ // If is vertical*******************************************************************************************************
if ($wor >= $width){ // If image source is bigger than final desire dimensions
$hcenter = ($hor/2)-($height/2); // center image source in height
$back = imagecreatetruecolor(round($width), round($height));
imagecopyresampled($back, $image, 0, -$hcenter, 0, 0, $wor, $hor, $wor, $hor);
} else { // If image source is not bigger than final desire dimensions
$hcenter = ($hor/2)-($height/2); // center image source in height
$hnu = ($hor*$width)/$wor;
$back = imagecreatetruecolor(round($width), round($height));
imagecopyresampled($back, $image, 0, -$hcenter, 0, 0, $width, $hnu, $wor, $hor);
}
} else { // If is portrait rectangular****************************************************************************************************
$ratio = $wor/$hor;
if($ratio > 1.3333333){ // If is portrait larger than 4:3
$wnu = ($wor*$height)/$hor;
$wcenter = ($wnu/2)-($width/2); // center image in width
$back = imagecreatetruecolor(round($width), round($height));
imagecopyresampled($back, $image, -$wcenter, 0, 0, 0, $wnu, $height, $wor, $hor);
} else { // If portrait is not larger than 4:3
$hnu = ($wor*$height)/$hor;
$hcenter = ($hnu/2)-($height/2); // center image source in height
$back = imagecreatetruecolor(round($width), round($height));
imagecopyresampled($back, $image, 0, -$hcenter, 0, 0, $width, $hnu, $wor, $hor);
}
}
// Blur Image
for ($x=1; $x <=40; $x++){
imagefilter($back, IMG_FILTER_GAUSSIAN_BLUR, 999);
}
imagefilter($back, IMG_FILTER_SMOOTH,99);
imagefilter($back, IMG_FILTER_BRIGHTNESS, 10);
// Getting the dimensions of the image
$src_w = imagesx($image2);
$src_h = imagesy($image2);
// Do some math to figure out which way we'll need to crop the image
// to get it proportional to the new size, then crop or adjust as needed
$x_ratio = $width / $src_w;
$y_ratio = $height / $src_h;
if (($src_w <= $width) && ($src_h <= $height)) {
$new_w = $src_w;
$new_h = $src_h;
} elseif (($x_ratio * $src_h) < $height) {
$new_h = ceil($x_ratio * $src_h);
$new_w = $width;
} else {
$new_w = ceil($y_ratio * $src_w);
$new_h = $height;
}
$front = imagecreatetruecolor(round($new_w), round($new_h));
imagecopyresampled($front, $image2, 0, 0, 0, 0, $new_w, $new_h, $src_w, $src_h);
if ($new_h >= $new_w){ // If is vertical image
$wctr = ($new_w/2)-($width/2);
imagecopymerge($back, $front,-$wctr, 0, 0, 0, $new_w, $new_h, 100);
} else { // if is portrait
$hctr = ($new_h/2)-($height/2);
imagecopymerge($back, $front,0, -$hctr, 0, 0, $new_w, $new_h, 100);
}
// output new file
imagejpeg($back,'00.jpg',90);
imagedestroy($back);
imagedestroy($front);
//*********************************************************************************
/**
Do other actions like send ajax responses, save in database, etc
**/
}
?>
But still need help to do this function script more secure and more short. I think that it is possible to reduce it more yet. Please i need your help. My brain was melt coding this function... still it need more test with different sizes of images, vertical, portrait, etc. Please help
There are many approaches, but I would suggest you use imagecopymerge instead of imagecopy. You provide the destination and source coordinates as well as the source size and voila!
However note that this way you won't keep transparency (for GIF/PNG, if present). To do it, have a look at this comment of Sina Salek in the PHP documentation: PNG ALPHA CHANNEL SUPPORT for imagecopymerge().
But I would agree with @LeeKowalkowski - in the long run, you should consider migrating to ImageMagick for many reasons - image quality above all.
EDIT: I forgot to mention, before merging, set transparent colour (the extended canvas) with imagecolortransparent. Then, Sina Salek's comment in PHP documentation (the link above).