Cropping images in PHP leaves black space - php

This is likely a duplicate, but every solution I have looked at seems to not work for me, so not sure what I am doing differently.
I don't understand too much about image manipulation yet, but cropping images seems to add lots of black space around the right/bottom of the image when using imagecopyresampled to place it over another. They are all JPEGs.
This is my crop function:
function thumbImage($thumb_img,$img_size,$shape){
$width = 250;
$height = 250;
list($w, $h) = $img_size;
if($w > $h) {
$new_height = $height;
$new_width = floor($w * ($new_height / $h));
$crop_x = ceil(($w - $h) / 2);
$crop_y = 0;
} else {
$new_width = $width;
$new_height = floor( $h * ( $new_width / $w ));
$crop_x = 0;
$crop_y = ceil(($h - $w) / 2);
}
$tmp_img = imagecreatetruecolor($width,$height);
imagecopyresampled($tmp_img, $thumb_img, 0, 0, $crop_x, $crop_y, $new_width, $new_height, $w, $h);
return $tmp_img;
}
Any solutions with an explanation of how it works would be greatly appreciated.

Try this:
function thumbImage($source_img,$max_size){
list($w, $h) = getimagesize($source_img);
if($w>$h){
$width = ($max_size/$h)*$w;
$height = $max_size;
}else{
$width = $max_size;
$height = ($max_size/$w)*$h;
}
$x = ($max_size-$width)/2;
$y = ($max_size-$height)/2;
$thumb_img = imagecreatetruecolor($max_size,$max_size);
imagecopyresampled($thumb_img, $source_img, $x, $y, 0, 0, $width, $height, $w, $h);
return $thumb_img;
}

Related

How to crop image like with object-fit:cover by php?

Could you help please, I crop image for thumbnail with php code below.
But some pictures crops with black frames at top and bottom. How to do it properly?
$w = 265;
$h = 198;
if (empty($w)) {
$w = ceil($h / ($height / $width));
}
if (empty($h)) {
$h = ceil($w / ($width / $height));
}
$tmp = imageCreateTrueColor($w, $h);
$tw = ceil($h / ($height / $width));
$th = ceil($w / ($width / $height));
if ($tw < $w) {
imageCopyResampled($tmp, $img, ceil(($w - $tw) / 2), 0, 0, 0, $tw, $h, $width, $height);
} else {
imageCopyResampled($tmp, $img, 0, ceil(($h - $th) / 2), 0, 0, $w, $th, $width, $height);
}
$img = $tmp;
Links to origninal photo and with black frames:

Trying to resize an image using PHP

Anybody know what's wrong with this code? Instead of giving me an actual image, it's giving me an image error. I think I set all the functions correctly and everything. Any suggestions would be awesome.
<?php
function resizeImage($filename, $max_width, $max_height) {
list($orig_width, $orig_height) = getimagesize($filename);
$width = $orig_width;
$height = $orig_height;
# taller
if ($height > $max_height) {
$width = ($max_height / $height) * $width;
$height = $max_height;
}
# wider
if ($width > $max_width) {
$height = ($max_width / $width) * $height;
$width = $max_width;
}
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0,
$width, $height, $orig_width, $orig_height);
return $image_p;
}
$directory = "uploads/";
$images = glob($directory."*");
foreach($images as $image) {
// Set a maximum height and width
$width = 200;
$height = 200;
$newImage = resizeImage($image, $width, $height);
echo '<img src="'.$newImage.'" /><br />';
}
?>
if you dont want to save the image, then you can use the below code.
<?php
function resizeImage($filename, $max_width, $max_height) {
list($orig_width, $orig_height) = getimagesize($filename);
$width = $orig_width;
$height = $orig_height;
# taller
if ($height > $max_height) {
$width = ($max_height / $height) * $width;
$height = $max_height;
}
# wider
if ($width > $max_width) {
$height = ($max_width / $width) * $height;
$width = $max_width;
}
$image_p = imagecreatetruecolor($width, $height);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $orig_width, $orig_height);
ob_start();
imagejpeg($image_p);
$imgSrc = 'data:image/jpeg;base64,'.base64_encode(ob_get_clean());
return $imgSrc;
}
$directory = "uploads/";
$images = glob($directory."*");
foreach($images as $image) {
// Set a maximum height and width
$width = 200;
$height = 200;
$imgSrc = resizeImage($image, $width, $height);
echo '<img src="'.$imgSrc.'" /><br />';
}
?>
if you want to save the image, then you have to create some other folder like resized and save cropped images there and link it as given below.(don't change your old code and add this)
<?php
$directory = "uploads/";
$images = glob($directory."*");
$i=1;//added
foreach($images as $image) {
// Set a maximum height and width
$width = 200;
$height = 200;
$newImage = resizeImage($image, $width, $height);
imagejpeg($newImage,"resized/newimage".$i.".jpg"); //added
echo '<img src="resized/newimage'.$i.'.jpg" /><br />';//modified
$i++;//added
}
?>

Crop center square of image using imagecopyresampled

I am trying to create 2 cropped thumbnails (60x60 and 150x150) from a normal sized image. Everything works fine apart from the cropping, which does not work. That part is producing a thumbnail with a black line down the right side like this:
.............
. ...
. ...
. ...
.............
The resizing works fine, as the end thumbnails have the correct heights of 60 and 150 (working from a landscape image as the original) but they still come out landscape.
What I have:
list($thumb_width, $thumb_height) = getimagesize($thumb_target);
if ($thumb_width > $thumb_height) { // landscape
$thumb1_new_height = 60;
$thumb1_new_width = floor( $thumb_width * ( $thumb1_new_height / $thumb_height ));
$thumb1_crop_x = ceil(($thumb_width - $thumb_height) / 2);
$thumb1_crop_y = 0;
$thumb2_new_height = 150;
$thumb2_new_width = floor( $thumb_width * ( $thumb2_new_height / $thumb_height ));
$thumb2_crop_x = ceil(($thumb_width - $thumb_height) / 2);
$thumb2_crop_y = 0;
}
else if ($thumb_width < $thumb_height){ // portrait
$thumb1_new_width = 60;
$thumb1_new_height = floor( $thumb_height * ( $thumb1_new_width / $thumb_width ));
$thumb1_crop_x = 0;
$thumb1_crop_y = ceil(($thumb_height - $thumb_width) / 2);
$thumb2_new_width = 150;
$thumb2_new_height = floor( $thumb_height * ( $thumb2_new_width / $thumb_width ));
$thumb2_crop_x = 0;
$thumb2_crop_y = ceil(($thumb_height - $thumb_width) / 2);
} else { // square
$thumb1_new_width = 60;
$thumb1_new_height = 60;
$thumb1_crop_x = 0;
$thumb1_crop_y = 0;
$thumb2_new_width = 150;
$thumb2_new_height = 150;
$thumb2_crop_x = 0;
$thumb2_crop_y = 0;
}
$thumb1_tmp_img = imagecreatetruecolor($thumb1_new_width,$thumb1_new_height);
$thumb2_tmp_img = imagecreatetruecolor($thumb2_new_width,$thumb2_new_height);
imagecopyresampled($thumb1_tmp_img, $thumb_img, 0, 0, $thumb1_crop_x, $thumb1_crop_y, $thumb1_new_width, $thumb1_new_height, $thumb_width, $thumb_height);
imagecopyresampled($thumb2_tmp_img, $thumb_img, 0, 0, $thumb2_crop_x, $thumb2_crop_y, $thumb2_new_width, $thumb2_new_height, $thumb_width, $thumb_height);
I think you are going wrong in your thumb1_tmp_img near the end. I made this a class so I didn't have to duplicate so much like you have, but you can see the changes. See if this does it for you:
class ImageFactory
{
public function MakeThumb($thumb_target = '', $width = 60,$height = 60,$SetFileName = false, $quality = 80)
{
$thumb_img = imagecreatefromjpeg($thumb_target);
// size from
list($w, $h) = getimagesize($thumb_target);
if($w > $h) {
$new_height = $height;
$new_width = floor($w * ($new_height / $h));
$crop_x = ceil(($w - $h) / 2);
$crop_y = 0;
}
else {
$new_width = $width;
$new_height = floor( $h * ( $new_width / $w ));
$crop_x = 0;
$crop_y = ceil(($h - $w) / 2);
}
// I think this is where you are mainly going wrong
$tmp_img = imagecreatetruecolor($width,$height);
imagecopyresampled($tmp_img, $thumb_img, 0, 0, $crop_x, $crop_y, $new_width, $new_height, $w, $h);
if($SetFileName == false) {
header('Content-Type: image/jpeg');
imagejpeg($tmp_img);
}
else
imagejpeg($tmp_img,$SetFileName,$quality);
imagedestroy($tmp_img);
}
}
// Initiate class
$ImageMaker = new ImageFactory();
// Here is just a test landscape sized image
$thumb_target = 'http://media1.santabanta.com/full6/Outdoors/Landscapes/landscapes-246a.jpg';
// 60px x 60px
$ImageMaker->MakeThumb($thumb_target,60,60,'image60px.jpg');
// Here is a portrait for testing
$thumb_target = 'http://imgc.allpostersimages.com/images/P-488-488-90/55/5543/L6HLG00Z/posters/warning-you-are-entering-a-fart-zone.jpg';
// 150px x 150px
$ImageMaker->MakeThumb($thumb_target,150,150,'image150px.jpg');

Image resize with php [duplicate]

This question already has answers here:
Resize image in PHP
(13 answers)
Closed 6 years ago.
function resize($originalImage){
list($width, $height) = getimagesize($originalImage);
$newName=basename($originalImage);
$imageResized = imagecreatetruecolor(128, 128);
$imageTmp = imagecreatefromjpeg ($originalImage);
imagecopyresampled($imageResized, $imageTmp, 0, 0, 0, 0, 128, 128, $width, $height);
imagejpeg($imageResized, "resizedImg/$newName",100);
imageDestroy($imageResized);
}
The script returns the image with the correct name but it's just black? Any ideas?
If you have trouble with image resizing use this code for it. Do the modifications as you need it.
function resizeImage($file){
define ('MAX_WIDTH', 1500);//max image width
define ('MAX_HEIGHT', 1500);//max image height
define ('MAX_FILE_SIZE', 10485760);
//iamge save path
$path = 'storeResize/';
//size of the resize image
$new_width = 128;
$new_height = 128;
//name of the new image
$nameOfFile = 'resize_'.$new_width.'x'.$new_height.'_'.basename($file['name']);
$image_type = $file['type'];
$image_size = $file['size'];
$image_error = $file['error'];
$image_file = $file['tmp_name'];
$image_name = $file['name'];
$image_info = getimagesize($image_file);
//check image type
if ($image_info['mime'] == 'image/jpeg' or $image_info['mime'] == 'image/jpg'){
}
else if ($image_info['mime'] == 'image/png'){
}
else if ($image_info['mime'] == 'image/gif'){
}
else{
//set error invalid file type
}
if ($image_error){
//set error image upload error
}
if ( $image_size > MAX_FILE_SIZE ){
//set error image size invalid
}
switch ($image_info['mime']) {
case 'image/jpg': //This isn't a valid mime type so we should probably remove it
case 'image/jpeg':
$image = imagecreatefromjpeg ($image_file);
break;
case 'image/png':
$image = imagecreatefrompng ($image_file);
break;
case 'image/gif':
$image = imagecreatefromgif ($image_file);
break;
}
if ($new_width == 0 && $new_height == 0) {
$new_width = 100;
$new_height = 100;
}
// ensure size limits can not be abused
$new_width = min ($new_width, MAX_WIDTH);
$new_height = min ($new_height, MAX_HEIGHT);
//get original image h/w
$width = imagesx ($image);
$height = imagesy ($image);
//$align = 'b';
$zoom_crop = 1;
$origin_x = 0;
$origin_y = 0;
//TODO setting Memory
// generate new w/h if not provided
if ($new_width && !$new_height) {
$new_height = floor ($height * ($new_width / $width));
} else if ($new_height && !$new_width) {
$new_width = floor ($width * ($new_height / $height));
}
// scale down and add borders
if ($zoom_crop == 3) {
$final_height = $height * ($new_width / $width);
if ($final_height > $new_height) {
$new_width = $width * ($new_height / $height);
} else {
$new_height = $final_height;
}
}
// create a new true color image
$canvas = imagecreatetruecolor ($new_width, $new_height);
imagealphablending ($canvas, false);
if (strlen ($canvas_color) < 6) {
$canvas_color = 'ffffff';
}
$canvas_color_R = hexdec (substr ($canvas_color, 0, 2));
$canvas_color_G = hexdec (substr ($canvas_color, 2, 2));
$canvas_color_B = hexdec (substr ($canvas_color, 2, 2));
// Create a new transparent color for image
$color = imagecolorallocatealpha ($canvas, $canvas_color_R, $canvas_color_G, $canvas_color_B, 127);
// Completely fill the background of the new image with allocated color.
imagefill ($canvas, 0, 0, $color);
// scale down and add borders
if ($zoom_crop == 2) {
$final_height = $height * ($new_width / $width);
if ($final_height > $new_height) {
$origin_x = $new_width / 2;
$new_width = $width * ($new_height / $height);
$origin_x = round ($origin_x - ($new_width / 2));
} else {
$origin_y = $new_height / 2;
$new_height = $final_height;
$origin_y = round ($origin_y - ($new_height / 2));
}
}
// Restore transparency blending
imagesavealpha ($canvas, true);
if ($zoom_crop > 0) {
$src_x = $src_y = 0;
$src_w = $width;
$src_h = $height;
$cmp_x = $width / $new_width;
$cmp_y = $height / $new_height;
// calculate x or y coordinate and width or height of source
if ($cmp_x > $cmp_y) {
$src_w = round ($width / $cmp_x * $cmp_y);
$src_x = round (($width - ($width / $cmp_x * $cmp_y)) / 2);
} else if ($cmp_y > $cmp_x) {
$src_h = round ($height / $cmp_y * $cmp_x);
$src_y = round (($height - ($height / $cmp_y * $cmp_x)) / 2);
}
// positional cropping!
if ($align) {
if (strpos ($align, 't') !== false) {
$src_y = 0;
}
if (strpos ($align, 'b') !== false) {
$src_y = $height - $src_h;
}
if (strpos ($align, 'l') !== false) {
$src_x = 0;
}
if (strpos ($align, 'r') !== false) {
$src_x = $width - $src_w;
}
}
// positional cropping!
imagecopyresampled ($canvas, $image, $origin_x, $origin_y, $src_x, $src_y, $new_width, $new_height, $src_w, $src_h);
} else {
imagecopyresampled ($canvas, $image, 0, 0, 0, 0, $new_width, $new_height, $width, $height);
}
//Straight from Wordpress core code. Reduces filesize by up to 70% for PNG's
if ( (IMAGETYPE_PNG == $image_info[2] || IMAGETYPE_GIF == $image_info[2]) && function_exists('imageistruecolor') && !imageistruecolor( $image ) && imagecolortransparent( $image ) > 0 ){
imagetruecolortopalette( $canvas, false, imagecolorstotal( $image ) );
}
$quality = 100;
$nameOfFile = 'resize_'.$new_width.'x'.$new_height.'_'.basename($file['name']);
if (preg_match('/^image\/(?:jpg|jpeg)$/i', $image_info['mime'])){
imagejpeg($canvas, $path.$nameOfFile, $quality);
} else if (preg_match('/^image\/png$/i', $image_info['mime'])){
imagepng($canvas, $path.$nameOfFile, floor($quality * 0.09));
} else if (preg_match('/^image\/gif$/i', $image_info['mime'])){
imagegif($canvas, $path.$nameOfFile);
}
}

Having issues with GD thumbnail generator

I'm using PHP to generate thumbnails. The problem is that I have a set width and height the thumbnails need to be and often times the images are stretched.
What I'd like is the image to remain at the same proportions and just have black filler (or any color) either on the left & right for tall images or top & bottom for wide images.
Here is the code I'm currently using: (dumbed down a bit for readability)
$temp_image_file = imagecreatefromjpeg("http://www.example.com/image.jpg");
list($width,$height) = getimagesize("http://www.example.com/image.jpg");
$image_file = imagecreatetruecolor(166,103);
imagecopyresampled($image_file,$temp_image_file,0,0,0,0,166,103,$width,$height);
imagejpeg($image_file,"thumbnails/thumbnail.jpg",50);
imagedestroy($temp_image_file);
imagedestroy($image_file);
You'll need to calculate the new width & height to keep the image proportionat. Check out example 2 on this page:
http://us3.php.net/imagecopyresampled
Okay got it working, here's what I ended up doing:
$filename = "http://www.example.com/image.jpg";
list($width,$height) = getimagesize($filename);
$width_ratio = 166 / $width;
if ($height * $width_ratio <= 103)
{
$adjusted_width = 166;
$adjusted_height = $height * $width_ratio;
}
else
{
$height_ratio = 103 / $height;
$adjusted_width = $width * $height_ratio;
$adjusted_height = 103;
}
$image_p = imagecreatetruecolor(166,103);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p,$image,ceil((166 - $adjusted_width) / 2),ceil((103 - $adjusted_height) / 2),0,0,ceil($adjusted_width),ceil($adjusted_height),$width,$height);
imagejpeg($image_p,"thumbnails/thumbnail.jpg",50);
Here's a function I wrote that takes a GD image object, max width, max height, and rescales within those parameters:
function resized($im, $mx, $my) {
$x = $nx = imagesx($im);
$y = $ny = imagesy($im);
$ar = $x / $y;
while ($nx > $mx || $ny > $my) {
if ($nx > $mx) {
$nx = $mx;
$ny = $nx / $ar;
}
if ($ny > $my) {
$ny = $my;
$nx = $ny * $ar;
}
}
if ($nx != $x) {
$im2 = imagecreatetruecolor($nx, $ny);
imagecopyresampled($im2, $im, 0, 0, 0, 0, $nx, $ny, $x, $y);
return $im2;
} else {
return $im;
}
}
If the resulting image doesn't need rescaling then it just returns the original image.
Have a look at this upload class. It does what you want and a lot more besides.
This rescales the image to the larger size of the width and height and then crops it to the correct size.
// Crete an image forced to width and height
function createFixedImage($img, $id=0, $preFix=false, $mw='100', $mh='100', $quality=90){
// Fix path
$filename = '../'.$img;
// Check for file
if(file_exists($filename))
{
// Set a maximum height and width
$width = $mw;
$height = $mh;
// Get new dimensions
list($width_orig, $height_orig) = getimagesize($filename);
$ratio_orig = $width_orig/$height_orig;
if ($width/$height < $ratio_orig) {
$width = $height*$ratio_orig;
}else{
$height = $width/$ratio_orig;
}
// Resample
$image_p = imagecreatetruecolor($mw, $mh);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $width, $height, $width_orig, $height_orig);
// Output
imagejpeg($image_p, "../images/stories/catalog/{$preFix}{$id}.jpg", $quality);
}
}

Categories