Crop image in PHP - php

The code below crops the image well, which is what i want, but for larger images, it wotn work as well. Is there any way of 'zooming out of the image'
Idealy i would be able to have each image roughly the same size before cropping so that i would get good results each time
Code is
<?php
$image = $_GET['src']; // the image to crop
$dest_image = 'images/cropped_whatever.jpg'; // make sure the directory is writeable
$img = imagecreatetruecolor('200','150');
$org_img = imagecreatefromjpeg($image);
$ims = getimagesize($image);
imagecopy($img,$org_img, 0, 0, 20, 20, 200, 150);
imagejpeg($img,$dest_image,90);
imagedestroy($img);
echo '<img src="'.$dest_image.'" ><p>';

If you are trying to generate thumbnails, you must first resize the image using imagecopyresampled();. You must resize the image so that the size of the smaller side of the image is equal to the corresponding side of the thumb.
For example, if your source image is 1280x800px and your thumb is 200x150px, you must resize your image to 240x150px and then crop it to 200x150px. This is so that the aspect ratio of the image won't change.
Here's a general formula for creating thumbnails:
$image = imagecreatefromjpeg($_GET['src']);
$filename = 'images/cropped_whatever.jpg';
$thumb_width = 200;
$thumb_height = 150;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
Haven't tested this but it should work.
EDIT
Now tested and working.

imagecopyresampled() will take a 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).
If the source and destination coordinates and width and heights differ, appropriate stretching or shrinking of the image fragment will be performed. The coordinates refer to the upper left corner.
This function can be used to copy regions within the same image. But if the regions overlap, the results will be unpredictable.
- Edit -
If $src_w and $src_h are smaller than $dst_w and $dst_h respectively, thumb image will be zoomed in. Otherwise it will be zoomed out.
<?php
$dst_x = 0; // X-coordinate of destination point
$dst_y = 0; // Y-coordinate of destination point
$src_x = 100; // Crop Start X position in original image
$src_y = 100; // Crop Srart Y position in original image
$dst_w = 160; // Thumb width
$dst_h = 120; // Thumb height
$src_w = 260; // Crop end X position in original image
$src_h = 220; // Crop end Y position in original image
// Creating an image with true colors having thumb dimensions (to merge with the original image)
$dst_image = imagecreatetruecolor($dst_w, $dst_h);
// Get original image
$src_image = imagecreatefromjpeg('images/source.jpg');
// Cropping
imagecopyresampled($dst_image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
// Saving
imagejpeg($dst_image, 'images/crop.jpg');
?>

php 5.5 has an imagecrop function http://php.net/manual/en/function.imagecrop.php

$image = imagecreatefromjpeg($_GET['src']);
Needs to be replaced with this:
$image = imagecreatefromjpeg('images/thumbnails/myimage.jpg');
Because imagecreatefromjpeg() is expecting a string.
This worked for me.
ref:
http://php.net/manual/en/function.imagecreatefromjpeg.php

HTML Code:-
enter code here
<!DOCTYPE html>
<html>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
Select image to upload:
<input type="file" name="image" id="fileToUpload">
<input type="submit" value="Upload Image" name="submit">
</form>
</body>
</html>
upload.php
enter code here
<?php
$image = $_FILES;
$NewImageName = rand(4,10000)."-". $image['image']['name'];
$destination = realpath('../images/testing').'/';
move_uploaded_file($image['image']['tmp_name'], $destination.$NewImageName);
$image = imagecreatefromjpeg($destination.$NewImageName);
$filename = $destination.$NewImageName;
$thumb_width = 200;
$thumb_height = 150;
$width = imagesx($image);
$height = imagesy($image);
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect )
{
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else
{
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
echo "cropped"; die;
?>

Improved Crop image functionality in PHP on the fly.
http://www.example.com/cropimage.php?filename=a.jpg&newxsize=100&newysize=200&constrain=1
Code in cropimage.php
$basefilename = #basename(urldecode($_REQUEST['filename']));
$path = 'images/';
$outPath = 'crop_images/';
$saveOutput = false; // true/false ("true" if you want to save images in out put folder)
$defaultImage = 'no_img.png'; // change it with your default image
$basefilename = $basefilename;
$w = $_REQUEST['newxsize'];
$h = $_REQUEST['newysize'];
if ($basefilename == "") {
$img = $path . $defaultImage;
$percent = 100;
} else {
$img = $path . $basefilename;
$len = strlen($img);
$ext = substr($img, $len - 3, $len);
$img2 = substr($img, 0, $len - 3) . strtoupper($ext);
if (!file_exists($img)) $img = $img2;
if (file_exists($img)) {
$percent = #$_GET['percent'];
$constrain = #$_GET['constrain'];
$w = $w;
$h = $h;
} else if (file_exists($path . $basefilename)) {
$img = $path . $basefilename;
$percent = $_GET['percent'];
$constrain = $_GET['constrain'];
$w = $w;
$h = $h;
} else {
$img = $path . 'no_img.png'; // change with your default image
$percent = #$_GET['percent'];
$constrain = #$_GET['constrain'];
$w = $w;
$h = $h;
}
}
// get image size of img
$x = #getimagesize($img);
// image width
$sw = $x[0];
// image height
$sh = $x[1];
if ($percent > 0) {
// calculate resized height and width if percent is defined
$percent = $percent * 0.01;
$w = $sw * $percent;
$h = $sh * $percent;
} else {
if (isset ($w) AND !isset ($h)) {
// autocompute height if only width is set
$h = (100 / ($sw / $w)) * .01;
$h = #round($sh * $h);
} elseif (isset ($h) AND !isset ($w)) {
// autocompute width if only height is set
$w = (100 / ($sh / $h)) * .01;
$w = #round($sw * $w);
} elseif (isset ($h) AND isset ($w) AND isset ($constrain)) {
// get the smaller resulting image dimension if both height
// and width are set and $constrain is also set
$hx = (100 / ($sw / $w)) * .01;
$hx = #round($sh * $hx);
$wx = (100 / ($sh / $h)) * .01;
$wx = #round($sw * $wx);
if ($hx < $h) {
$h = (100 / ($sw / $w)) * .01;
$h = #round($sh * $h);
} else {
$w = (100 / ($sh / $h)) * .01;
$w = #round($sw * $w);
}
}
}
$im = #ImageCreateFromJPEG($img) or // Read JPEG Image
$im = #ImageCreateFromPNG($img) or // or PNG Image
$im = #ImageCreateFromGIF($img) or // or GIF Image
$im = false; // If image is not JPEG, PNG, or GIF
if (!$im) {
// We get errors from PHP's ImageCreate functions...
// So let's echo back the contents of the actual image.
readfile($img);
} else {
// Create the resized image destination
$thumb = #ImageCreateTrueColor($w, $h);
// Copy from image source, resize it, and paste to image destination
#ImageCopyResampled($thumb, $im, 0, 0, 0, 0, $w, $h, $sw, $sh);
//Other format imagepng()
if ($saveOutput) { //Save image
$save = $outPath . $basefilename;
#ImageJPEG($thumb, $save);
} else { // Output resized image
header("Content-type: image/jpeg");
#ImageJPEG($thumb);
}
}

You can use imagecrop function in (PHP 5 >= 5.5.0, PHP 7)
Example:
<?php
$im = imagecreatefrompng('example.png');
$size = min(imagesx($im), imagesy($im));
$im2 = imagecrop($im, ['x' => 0, 'y' => 0, 'width' => $size, 'height' => $size]);
if ($im2 !== FALSE) {
imagepng($im2, 'example-cropped.png');
imagedestroy($im2);
}
imagedestroy($im);
?>

$image = imagecreatefromjpeg($_GET['src']);
$filename = 'images/cropped_whatever.jpg'
Must be replaced with:
$image = imagecreatefromjpeg($_GET['src']);
Then it will work!

Related

scale an image proportionally without knowing both dimensions

$newimg = imagecreatefromjpeg($tempname);
Now I need to scale this image proportionally but don't know both dimensions in advance.
$newimg = imagescale($newimg, 160, auto, IMG_BICUBIC); //doesn't work
or
$newimg = imagescale($newimg, auto, 160, IMG_BICUBIC); // doesn't work
Is there a way to say auto or something to calculate width or height automatically.
If no, how can I calculate this?
The accepted solution here doesn't work. I doesn't keep aspect ratio.
I made a function that will do what you need. I have tested this function with scaling down images and it works as intended.
This function will size an image preserving the aspect ratio to completely fit inside the dimensions that you specify. The image will also be centered.
The function also has the ability to crop. If you use the crop parameter, it will oversize the image to make sure the smallest side of the image fills the desired dimensions. It will then crop the image to fit inside the dimensions, thus completely filling the given dimensions. The image will be centered.
Here is the function:
function scaleMyImage($filePath, $newPath, $newSize, $crop = NULL){
$img = imagecreatefromstring(file_get_contents($filePath));
$dst_x = 0;
$dst_y = 0;
$width = imagesx($img);
$height = imagesy($img);
$newWidth = $newSize;
$newHeight = $newSize;
if($width < $height){ //Portrait.
if($crop){
$newWidth = floor($width * ($newSize / $width));
$newHeight = floor($height * ($newSize / $width));
$dst_y = (floor(($newHeight - $newSize)/2)) * -1;
}else{
$newWidth = floor($width * ($newSize / $height));
$newHeight = $newSize;
$dst_x = floor(($newSize - $newWidth)/2);
}
} elseif($width > $height) { //Landscape
if($crop){
$newWidth = floor($width * ($newSize / $height));
$newHeight = floor($height * ($newSize / $height));
$dst_x = (floor(($newWidth - $newSize)/2)) * -1;
}else{
$newWidth = $newSize;
$newHeight = floor($height * ($newSize / $width));
$dst_y = floor(($newSize - $newHeight)/2);
}
}
$finalImage = imagecreatetruecolor($newSize, $newSize);
imagecopyresampled($finalImage, $img, $dst_x, $dst_y, 0, 0, $newWidth, $newHeight, $width, $height);
imagejpeg($finalImage, $newPath, 60); //Set your compression.
imagedestroy($img);
imagedestroy($finalImage);
}
How to use:
$newSize = 160;
$filePath = 'path/myImg.jpg';
$newPath = 'path/newImg.jpg';
$crop = 1; //Set to NULL if you don't want to crop.
scaleMyImage($filePath, $newPath, $newSize, 1);
This should do exactly what you want with the crop parameter set to 1.
First of all you will have to mention al-least one dimension (either height or width) then using aspect ration of original image you can identify another. Here is a sample code which i used in my case:
$width = 160; // User-defined
$height = ''; // User-defined
$path = $uploadDir . '/' . $tempname;
$mime = getimagesize($path);
// Load original image
if($mime['mime']=='image/png') {
$orig_img = imagecreatefrompng($path);
}
if($mime['mime']=='image/jpg' || $mime['mime']=='image/jpeg' || $mime['mime']=='image/pjpeg') {
$orig_img = imagecreatefromjpeg($path);
}
// Get original image height and width
$width_orig = imagesx($orig_img);
$height_orig = imagesy($orig_img);
// Aspect ratio of original image
$aspectRatio = $width_orig / $height_orig;
// If any one dimension available then calculate other with the help of aspect-ratio of original image
if ($width == '' && $height != '') {
$newheight = $height;
$newwidth = round($height * $aspectRatio);
}
if ($width != '' && $height == '') {
$newheight = round($width / $aspectRatio);
$newwidth = $width;
}
$newimg = imagescale($orig_img, $newwidth, $newheight, IMG_BICUBIC);

Resize an image in php with max height and width

Ok so I'm trying to resize an image using php. I do not have access to install plugins on the server I use at this time.
$originalimage is the actual original image that I'm going to resize.
$width is another parameter to define $original_width. The same can be said for $height and $original_height.
$original_width = imagesx($originalimage);
$original_height = imagesy($originalimage);
$max_width = $thumbwidth;
$max_height = $thumbheight;
$width = $original_width;
$height = $original_height;
Using the pre-setup above I start to work on this one here. This works but no way to set a max height. For example I pass a max width as $thumbwidth and max height as $thumbheight and this will work as desired till I then try to go ahead and use an image that's higher than it is wide. (Portrait image.) It does not completely fail however it does fail to enforce a max height, rendering an image that can potentially be very high.
if ($width > $height) {
$newwidth = $thumbwidth;
$divisor = $width / $thumbwidth;
$newheight = floor( $height / $divisor);
} else {
$newheight = $thumbheight;
$divisor = $height / $thumbheight;
$newwidth = floor( $width / $divisor );
}
$image = imagecreatetruecolor( $newwidth, $newheight );
imagecopyresampled( $image, $originalimage, 0, 0, 0, 0, $newwidth, $newheight, $original_width, $original_height );
After trying to understand this and failing after a few hours I came up with the code below which I had gotten from php.net. As you can see there was a reason I set two sets of variables equal to each other in the pre-setup part of the code. Mostly because I can not comprehend calling $max_width as $thumbwidth in the second code segment.
This below works as well until you pass in a parameter though that is larger than the width or height of $originalimage.
# 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 = imagecreatetruecolor( $width, $height );
imagecopyresampled( $image, $originalimage, 0, 0, 0, 0, $width, $height, $original_width, $original_height );
I'm sorry I can't find a way to do this on my own. As for this being a duplicate question, Most similar questions end up with "[Insert plugin name here] is better use that instead." I am asking specifically for an answer that does not use other plugins or javascript. (Besides GD which is pre-installed on my server.)
Before I end this question I will say that I am using imagejpeg($image); so the use of HTML or CSS is completely forbidden.
Here's a class I whipped up for a program I worked on. maybe it will help you?
<?php
class ImageHelper
{
/**
* #static
* #param $source string Path for source image
* #param $destination string Path for destination image to be placed
* #param $targetWidth int Width of the new image (in pixels)
* #param $targetHeight int Height of the new image (in pixels)
* #param $strict bool
*/
public static function createImage($source, $destination, $targetWidth, $targetHeight, $strict = false){
$dir = dirname($destination);
if(!is_dir($dir)){
mkdir($dir, 0770, true);
}
$fileContents = file_get_contents($source);
$image = imagecreatefromstring($fileContents);
$thumbnail = ImageHelper::resizeImage($image, $targetWidth, $targetHeight, $strict);
imagejpeg($thumbnail, $destination, 100);
imagedestroy($thumbnail);
imagedestroy($image);
}
/**
* Resize an image to the specified dimensions
* #param string $original Path to the original image
* #param int $targetWidth Width of the new image (in pixels)
* #param int $targetHeight Height of the new image (in pixels)
* #param bool $strict True to crop the picture to the specified dimensions, false for best fit
* #return bool|resource Returns the new image resource or false if the image was not resized.
*/
public static function resizeImage($original, $targetWidth, $targetHeight, $strict = false)
{
$originalWidth = imagesx($original);
$originalHeight = imagesy($original);
$widthRatio = $targetWidth / $originalWidth;
$heightRatio = $targetHeight / $originalHeight;
if(($widthRatio > 1 || $heightRatio > 1) && !$strict){
// don't scale up an image if either targets are greater than the original sizes and we aren't using a strict parameter
$dstHeight = $originalHeight;
$dstWidth = $originalWidth;
$srcHeight = $originalHeight;
$srcWidth = $originalWidth;
$srcX = 0;
$srcY = 0;
}elseif ($widthRatio > $heightRatio) {
// width is the constraining factor
if ($strict) {
$dstHeight = $targetHeight;
$dstWidth = $targetWidth;
$srcHeight = $originalHeight;
$srcWidth = $heightRatio * $targetWidth;
$srcX = floor(($originalWidth - $srcWidth) / 2);
$srcY = 0;
} else {
$dstHeight = ($originalHeight * $targetWidth) / $originalWidth;
$dstWidth = $targetWidth;
$srcHeight = $originalHeight;
$srcWidth = $originalWidth;
$srcX = 0;
$srcY = 0;
}
} else {
// height is the constraining factor
if ($strict) {
$dstHeight = $targetHeight;
$dstWidth = $targetWidth;
$srcHeight = $widthRatio * $targetHeight;
$srcWidth = $originalWidth;
$srcY = floor(($originalHeight - $srcHeight) / 2);
$srcX = 0;
} else {
$dstHeight = $targetHeight;
$dstWidth = ($originalWidth * $targetHeight) / $originalHeight;
$srcHeight = $originalHeight;
$srcWidth = $originalWidth;
$srcX = 0;
$srcY = 0;
}
}
$new = imagecreatetruecolor($dstWidth, $dstHeight);
if ($new === false) {
return false;
}
imagecopyresampled($new, $original, 0, 0, $srcX, $srcY, $dstWidth, $dstHeight, $srcWidth, $srcHeight);
return $new;
}
}
You can try this function as shown below.
<?php
function makeThumbnail($sourcefile,$max_width, $max_height, $endfile, $type){
// Takes the sourcefile (path/to/image.jpg) and makes a thumbnail from it
// and places it at endfile (path/to/thumb.jpg).
// Load image and get image size.
//
switch($type){
case'image/png':
$img = imagecreatefrompng($sourcefile);
break;
case'image/jpeg':
$img = imagecreatefromjpeg($sourcefile);
break;
case'image/gif':
$img = imagecreatefromgif($sourcefile);
break;
default :
return 'Un supported format';
}
$width = imagesx( $img );
$height = imagesy( $img );
if ($width > $height) {
if($width < $max_width)
$newwidth = $width;
else
$newwidth = $max_width;
$divisor = $width / $newwidth;
$newheight = floor( $height / $divisor);
}
else {
if($height < $max_height)
$newheight = $height;
else
$newheight = $max_height;
$divisor = $height / $newheight;
$newwidth = floor( $width / $divisor );
}
// Create a new temporary image.
$tmpimg = imagecreatetruecolor( $newwidth, $newheight );
imagealphablending($tmpimg, false);
imagesavealpha($tmpimg, true);
// Copy and resize old image into new image.
imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height);
// Save thumbnail into a file.
//compressing the file
switch($type){
case'image/png':
imagepng($tmpimg, $endfile, 0);
break;
case'image/jpeg':
imagejpeg($tmpimg, $endfile, 100);
break;
case'image/gif':
imagegif($tmpimg, $endfile, 0);
break;
}
// release the memory
imagedestroy($tmpimg);
imagedestroy($img);
}
?>
The function has five parameters.
> $sourcefile - Specicifies the temporary location of your image file
> $max_width - Specifies the possible maximum width
> $max_height - Specifies the possible maximum width
> $endfile - Specifies the directory to save the image
> $type - Specifies the image file type
Download demo code here
I've had a very similar problem building the thumbs for a gallery page. I tried Daniel Nyamasyo solution above but just could not get past the "$img = imagecreatefromjpeg($sourcefile);" line without getting "Warning: imagecreatefromjpeg failed to open stream: HTTP request failed! HTTP/1.1 400 Bad Request" no matter what $sourcefile I fed it.
I came up with this dirty method.
<?php
// Some variables
$thumb_width = 162; // The maximum values you want
$thumb_height = 122;
$thumb_pointer = 'thumbs'; // Put your output folder here which must exist
$img = imagecreatefromjpeg( $image_name);
$width = imagesx( $img );
$height = imagesy( $img );
if ($width>=$height)
{
// Now calculate thumbnail size
$new_width = $thumb_width;
$new_height = floor( $height * ($thumb_width / $width));
// The 'dirty' bit I found was needed for square or near square images
while ($new_height > $thumb_height)
{
$new_width = floor($new_width * 0.99);
$new_height = floor($new_height * 0.99);
}
}
else
{
$new_height = $thumb_height;
$new_width = floor($width * ($thumb_height / $height));
}
// Create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// Copy and resize old image into new image
imagecopyresized( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
// Save the thumbnail into a file
imagejpeg( $tmp_img, $thumb_pointer.'/'.$image_name);
?>

Saving a jpg as a transparent png with php

I have a function created which processes images in different ways based on the parameters. I have comments in the function to explain a bit.
Everything works with exception to when I take a jpg image and save it as a png. I just checked, even if I use imagepng() but save it with the extension .jpg, the image displays while properly resized, but with a .jpg extension. However, if I upload the same .jpg image, use imagepng() and save it with a .png extension, I get an image of the expected width and height after the resize, in a png format, with a .png extension. While the whole image is 100% transparent I have a 1px by 1px black pixel in the top left corner.
I would appreciate it if anyone can look at this and see if they see something I am missing. I believe the 1px X 1px is coming from the point I use for the imagefill(), but I don't understand why; it should be filling all transparent as with the rest of the image.
Here is my function:
if(!function_exists("upload")){
//$image = $image file name
//$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
//$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
//$proportion = 2,1,0;
//------ 2 = Preserve proportions while adding a border to fill width and height
//------ 1 = retain proportion to fit within both given width and height
//------ 0 = disregard proportions and resize to the exact width and height
function upload($image, $width, $height, $proportion){
// IS GD HERE?
$gdv = get_gd_info();
if (!$gdv){
return FALSE;
}
// GET AN IMAGE THING
$ext = trim(strtolower(end(explode('.', $image))));
list($imageX, $imageY, $type) = getimagesize($image); //gets information about new server image
// GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
$ratio_w = ($width / $imageX);
$ratio_h = ($height / $imageY);
$ratio = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;
if($width == 0){
if($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($height == 0){
if ($imageX > $width){
$newWidth = $width;
$newHeight = ($width/$imageX) * $imageY;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($proportion == 2){
// COMPUTE THUMBNAIL IMAGE DIMENSIONS
$newWidth = $imageX * $ratio;
$newHeight = $imageY * $ratio;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = ($width - $newWidth) / 2.0;
$fromMidY = ($height - $newHeight) / 2.0;
}elseif($proportion == 1){
if ($imageX > $width){
$newHeight = ($width/$imageX) * $imageY;
$newWidth = $width;
}
if ($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}
$fromMidY = 0;
$fromMidX = 0;
}elseif($proportion == 0){
$newWidth = $width;
$newHeight = $height;
$fromMidY = 0;
$fromMidX = 0;
}
switch(strtoupper($ext))
{
case 'JPG' :
case 'JPEG' :
$source = imagecreatefromjpeg($image);
break;
case 'PNG' :
$source = imagecreatefrompng($image);
break;
default : die("UNKNOWN IMAGE TYPE: $image");
}
// WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
if ($gdv >= 2)
{
// IF GD IS AT LEVEL 2 OR ABOVE
$target = imagecreatetruecolor($width, $height);
$color = imagecolorallocatealpha($target, 0, 0, 0, 127);
imagefill($target, 0, 0, $color);
imagesavealpha($target, TRUE);
imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
else
{
// IF GD IS AT A LOWER REVISION LEVEL
$target = imagecreate($width, $height);
imagesavealpha($target, TRUE);
$empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
imagefill($target, 0, 0, $empty);
imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
// SHARPEN THE PIC
$sharpenMatrix = array
( array( -1.2, -1, -1.2 )
, array( -1, 20, -1 )
, array( -1.2, -1, -1.2 )
)
;
$divisor = array_sum(array_map('array_sum', $sharpenMatrix));
$offset = 0;
imageconvolution($target, $sharpenMatrix, $divisor, $offset);
if(imagepng($target, $image,9)){
imagedestroy($target);
}else{
}
return $image;
}
}
EDIT 1: I guess I should have noted that I am uploading a .jpg image (Ex: 100px X 200px) and converting them to .png (Ex: 400px X 200px) but am retaining the proportions of the image to fit perfectly in the center of the destination .png. So I would have a 400px X 200px .png with my image in the center and 100px on the left and right which should be transparent. This way it fits nicely in a slider without a solid color as a fill. So an example of my call to my function would be upload($image, 400, 200, 2).
I figured out what the issue was. The portion of code which decides whether I should use imagecreatefromjpeg or imagecreatefrompng was incorrectly going off of the extension of the passed image and NOT by its mime type. I switched it to this:
switch($type)
{
case '2' :
$source = imagecreatefromjpeg($image);
break;
case '3' :
$source = imagecreatefrompng($image);
break;
default : die("UNKNOWN IMAGE TYPE: $image");
}
where $type is coming from the line I had in there
list($imageX, $imageY, $type) = getimagesize($image);
So all together the function is:
if(!function_exists("upload")){
//$image = $image file name
//$width = intended width of resized image, if 0 it will proportion to height, overrides proportion
//$height = intended width of resized image, if 0 it will proportion to width, overrides proportion
//$proportion = 2,1,0;
//------ 2 = Preserve proportions while adding a border to fill width and height
//------ 1 = retain proportion to fit within both given width and height
//------ 0 = disregard proportions and resize to the exact width and height
function upload($image, $width, $height, $proportion){
// IS GD HERE?
$gdv = get_gd_info();
if (!$gdv){
return FALSE;
}
// GET AN IMAGE THING
$ext = trim(strtolower(end(explode('.', $image))));
list($imageX, $imageY, $type) = getimagesize($image); //gets information about new server image
// GET THE LESSER OF THE RATIO OF THUMBNAIL H OR W DIMENSIONS
$ratio_w = ($width / $imageX);
$ratio_h = ($height / $imageY);
$ratio = ($ratio_w < $ratio_h) ? $ratio_w : $ratio_h;
if($width == 0){
if($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($height == 0){
if ($imageX > $width){
$newWidth = $width;
$newHeight = ($width/$imageX) * $imageY;
}else{
$newHeight = $imageY;
$newWidth = $imageX;
}
$width = $newWidth;
$height = $newHeight;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = 0;
$fromMidY = 0;
}elseif($proportion == 2){
// COMPUTE THUMBNAIL IMAGE DIMENSIONS
$newWidth = $imageX * $ratio;
$newHeight = $imageY * $ratio;
// COMPUTE THUMBNAIL IMAGE CENTERING OFFSETS
$fromMidX = ($width - $newWidth) / 2.0;
$fromMidY = ($height - $newHeight) / 2.0;
}elseif($proportion == 1){
if ($imageX > $width){
$newHeight = ($width/$imageX) * $imageY;
$newWidth = $width;
}
if ($imageY > $height){
$newHeight = $height;
$newWidth = ($height/$imageY) * $imageX;
}
$fromMidY = 0;
$fromMidX = 0;
}elseif($proportion == 0){
$newWidth = $width;
$newHeight = $height;
$fromMidY = 0;
$fromMidX = 0;
}
switch($type)
{
case '2' :
$source = imagecreatefromjpeg($image);
break;
case '3' :
$source = imagecreatefrompng($image);
break;
default : die("UNKNOWN IMAGE TYPE: $image");
}
// WHICH FUNCTIONS CAN RESIZE / RESAMPLE THE IMAGE?
if ($gdv >= 2)
{
// IF GD IS AT LEVEL 2 OR ABOVE
$target = imagecreatetruecolor($width, $height);
$color = imagecolorallocatealpha($target, 0, 0, 0, 127);
imagefill($target, 0, 0, $color);
imagesavealpha($target, TRUE);
imagecopyresampled ($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
else
{
// IF GD IS AT A LOWER REVISION LEVEL
$target = imagecreate($width, $height);
imagesavealpha($target, TRUE);
$empty = imagecolorallocatealpha($thumb,0x00,0x00,0x00,127);
imagefill($target, 0, 0, $empty);
imagecopyresized($target, $source, $fromMidX, $fromMidY, 0, 0, $newWidth, $newHeight, $imageX, $imageY);
}
// SHARPEN THE PIC
$sharpenMatrix = array
( array( -1.2, -1, -1.2 )
, array( -1, 20, -1 )
, array( -1.2, -1, -1.2 )
)
;
$divisor = array_sum(array_map('array_sum', $sharpenMatrix));
$offset = 0;
imageconvolution($target, $sharpenMatrix, $divisor, $offset);
if(imagepng($target, $image,9)){
imagedestroy($target);
}
return $image;
}
}
And an example call would be: upload("path/to/image/on/server.png", 400, 200, 2)
Where the image path can be either in a jpg or png mime type. But the extension MUST be .png. I suppose I can make it smarter where you can have any extension, but with the current code which uses this function it makes more sense for me to leave it as is. I would like to eventually add the option to turn on or off the transparency and instead use a solid color such as black if it is needed. Feel free to use and modify this.
There are nice hex2rgb/rgb2hex functions which I plan on using for this here

PHP crop image to fix width and height without losing dimension ratio

im looking to create thumbnails that has 100px by 100px dimension. i've seen many articles explaining the methods but most end up having the width!=height if the dimension ratio is to be kept.
for example, i have a 450px by 350px image. i would like to crop to 100px by 100px. if i were to keep the ratio, i would end up having 100px by 77px. this makes it ugly when im listing these images in a row and column. however, a image without dimension ratio will look terrible as well.
i've seen images from flickr and they look fantastic. for example:
thumbnail: http://farm1.static.flickr.com/23/32608803_29470dfeeb_s.jpg
medium size: http://farm1.static.flickr.com/23/32608803_29470dfeeb.jpg
large size: http://farm1.static.flickr.com/23/32608803_29470dfeeb_b.jpg
tks
This is done by only using a part of the image as the thumbnail which has a 1:1 aspect ratio (mostly the center of the image). If you look closely you can see it in the flickr thumbnail.
Because you have "crop" in your question, I'm not sure if you didn't already know this, but what do you want to know then?
To use cropping, here is an example:
//Your Image
$imgSrc = "image.jpg";
//getting the image dimensions
list($width, $height) = getimagesize($imgSrc);
//saving the image into memory (for manipulation with GD Library)
$myImage = imagecreatefromjpeg($imgSrc);
// calculating the part of the image to use for thumbnail
if ($width > $height) {
$y = 0;
$x = ($width - $height) / 2;
$smallestSide = $height;
} else {
$x = 0;
$y = ($height - $width) / 2;
$smallestSide = $width;
}
// copying the part into thumbnail
$thumbSize = 100;
$thumb = imagecreatetruecolor($thumbSize, $thumbSize);
imagecopyresampled($thumb, $myImage, 0, 0, $x, $y, $thumbSize, $thumbSize, $smallestSide, $smallestSide);
//final output
header('Content-type: image/jpeg');
imagejpeg($thumb);
Crop image with square based on lesser width or height
public function croppThis($target_url) {
$this->jpegImgCrop($target_url);
}
$target_url - is Name of image.
public function jpegImgCrop($target_url) {//support
$image = imagecreatefromjpeg($target_url);
$filename = $target_url;
$width = imagesx($image);
$height = imagesy($image);
$image_type = imagetypes($image); //IMG_GIF | IMG_JPG | IMG_PNG | IMG_WBMP | IMG_XPM
if($width==$height) {
$thumb_width = $width;
$thumb_height = $height;
} elseif($width<$height) {
$thumb_width = $width;
$thumb_height = $width;
} elseif($width>$height) {
$thumb_width = $height;
$thumb_height = $height;
} else {
$thumb_width = 150;
$thumb_height = 150;
}
$original_aspect = $width / $height;
$thumb_aspect = $thumb_width / $thumb_height;
if ( $original_aspect >= $thumb_aspect ) {
// If image is wider than thumbnail (in aspect ratio sense)
$new_height = $thumb_height;
$new_width = $width / ($height / $thumb_height);
}
else {
// If the thumbnail is wider than the image
$new_width = $thumb_width;
$new_height = $height / ($width / $thumb_width);
}
$thumb = imagecreatetruecolor( $thumb_width, $thumb_height );
// Resize and crop
imagecopyresampled($thumb,
$image,
0 - ($new_width - $thumb_width) / 2, // Center the image horizontally
0 - ($new_height - $thumb_height) / 2, // Center the image vertically
0, 0,
$new_width, $new_height,
$width, $height);
imagejpeg($thumb, $filename, 80);
}
You can use this code.
You need to pass source image path and thumbnail size in px, and optional destination path. if you pass it will save the image else the thumb will be shown.
Only jpg, jpeg and png are allowed.
function cropImage($sourcePath, $thumbSize, $destination = null) {
$parts = explode('.', $sourcePath);
$ext = $parts[count($parts) - 1];
if ($ext == 'jpg' || $ext == 'jpeg') {
$format = 'jpg';
} else {
$format = 'png';
}
if ($format == 'jpg') {
$sourceImage = imagecreatefromjpeg($sourcePath);
}
if ($format == 'png') {
$sourceImage = imagecreatefrompng($sourcePath);
}
list($srcWidth, $srcHeight) = getimagesize($sourcePath);
// calculating the part of the image to use for thumbnail
if ($srcWidth > $srcHeight) {
$y = 0;
$x = ($srcWidth - $srcHeight) / 2;
$smallestSide = $srcHeight;
} else {
$x = 0;
$y = ($srcHeight - $srcWidth) / 2;
$smallestSide = $srcWidth;
}
$destinationImage = imagecreatetruecolor($thumbSize, $thumbSize);
imagecopyresampled($destinationImage, $sourceImage, 0, 0, $x, $y, $thumbSize, $thumbSize, $smallestSide, $smallestSide);
if ($destination == null) {
header('Content-Type: image/jpeg');
if ($format == 'jpg') {
imagejpeg($destinationImage, null, 100);
}
if ($format == 'png') {
imagejpeg($destinationImage);
}
if ($destination = null) {
}
} else {
if ($format == 'jpg') {
imagejpeg($destinationImage, $destination, 100);
}
if ($format == 'png') {
imagepng($destinationImage, $destination);
}
}
}
I like using GDLib to fiddle with images, it's fantastically easy to work with also. There are lots of blog posts and tutorials out there. I would recommend using a class for it or similar though, as taking care of all the variations in the image can be very time consuming.
To complete #SvenKoschnicke code, here is little tool to process other image formats:
$sourceProperties = getimagesize($imgSrc);
$width = $sourceProperties[0];
$height = $sourceProperties[1];
switch ($sourceProperties[2]) {
case IMAGETYPE_PNG:
$myImage = imagecreatefrompng($imgSrc);
break;
case IMAGETYPE_GIF:
$myImage = imagecreatefromgif($imgSrc);
break;
case IMAGETYPE_JPEG:
$myImage = imagecreatefromjpeg($imgSrc);
break;
}

image crop showing black bg

i have this image crop code that when the image does get cropped a black background is added in the picture. how can i remove it? thanks
$fldcategory = $_POST['category'];
$flname = $_FILES['upload']['name'];
$img_src = $_FILES['upload']['tmp_name'];
$thumb = "uploads/" . $flname;
$title = $_POST['title'];
// Open image
$img = imagecreatefromjpeg($img_src);
// Store image width and height
list($img_width, $img_height) = getimagesize($img_src);
$width = '800';
$height = '600';
// 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);
Have a look at these functions:
http://ch2.php.net/imagecolortransparent
http://ch2.php.net/imagefill
You can define a color as transparent with the first function (you must allocate that color). Fill the new image with the transparent color before you paint the resized version on it. This will only make your black bg invisible and won't crop the image to the right size. (This is only a guess of what could help you)

Categories