crop an image after resizing in GD library - php

I need to first resize an image proportionally (the width is the important dimension) and then crop afterwards to chop of any excess height and then store the new version in a directory.
I've managed to do the resizing fine and I end up with images that are the correct width in my directory. Somehwere in here I need to crop the excess height off. But I can't work out where I need to do it. Do I need to use copyimageresampled somehow. I want to crop all images so they're 50px in height.
Here's what I have so far fo the resizing:
$src = ImageCreateFromJpeg($upfile);
$dst = ImageCreateTrueColor($tn_width, $tn_height);
ImageCopyResized($dst, $src, 0, 0, 0, 0, $tn_width, $tn_height, $width, $height);
ImageJpeg($dst, 'images/' . $_FILES['image']['name']);

This is what I was after. A 2 stage process. The trick is to resize the image in to a temporary image and then crop it:
http://salman-w.blogspot.com/2009/04/crop-to-fit-image-using-aspphp.html

This might help you to crop after resize: 911-need-code-help
<?php
//----------------------------------------------------------------
// Crop-to-fit PHP-GD
// Revision 2 [2009-06-01]
// Corrected aspect ratio of the output image
//----------------------------------------------------------------
define( 'DESIRED_IMAGE_WIDTH', 150 );
define( 'DESIRED_IMAGE_HEIGHT', 150 );
$source_path = $_FILES[ 'Image1' ][ 'tmp_name' ];
//
// Add file validation code here
//
list( $source_width, $source_height, $source_type ) = getimagesize( $source_path );
switch ( $source_type )
{
case IMAGETYPE_GIF:
$source_gdim = imagecreatefromgif( $source_path );
break;
case IMAGETYPE_JPEG:
$source_gdim = imagecreatefromjpeg( $source_path );
break;
case IMAGETYPE_PNG:
$source_gdim = imagecreatefrompng( $source_path );
break;
}
$source_aspect_ratio = $source_width / $source_height;
$desired_aspect_ratio = DESIRED_IMAGE_WIDTH / DESIRED_IMAGE_HEIGHT;
if ( $source_aspect_ratio > $desired_aspect_ratio )
{
//
// Triggered when source image is wider
//
$temp_height = DESIRED_IMAGE_HEIGHT;
$temp_width = ( int ) ( DESIRED_IMAGE_HEIGHT * $source_aspect_ratio );
}
else
{
//
// Triggered otherwise (i.e. source image is similar or taller)
//
$temp_width = DESIRED_IMAGE_WIDTH;
$temp_height = ( int ) ( DESIRED_IMAGE_WIDTH / $source_aspect_ratio );
}
//
// Resize the image into a temporary GD image
//
$temp_gdim = imagecreatetruecolor( $temp_width, $temp_height );
imagecopyresampled(
$temp_gdim,
$source_gdim,
0, 0,
0, 0,
$temp_width, $temp_height,
$source_width, $source_height
);
//
// Copy cropped region from temporary image into the desired GD image
//
$x0 = ( $temp_width - DESIRED_IMAGE_WIDTH ) / 2;
$y0 = ( $temp_height - DESIRED_IMAGE_HEIGHT ) / 2;
$desired_gdim = imagecreatetruecolor( DESIRED_IMAGE_WIDTH, DESIRED_IMAGE_HEIGHT );
imagecopy(
$desired_gdim,
$temp_gdim,
0, 0,
$x0, $y0,
DESIRED_IMAGE_WIDTH, DESIRED_IMAGE_HEIGHT
);
//
// Render the image
// Alternatively, you can save the image in file-system or database
//
header( 'Content-type: image/jpeg' );
imagejpeg( $desired_gdim );
//
// Add clean-up code here
//
?>

Croping is just like resizing with GD
Some sample code:
// Original image
$filename = 'someimage.jpg';
// Get dimensions of the original image
list($current_width, $current_height) = getimagesize($filename);
// The x and y coordinates on the original image where we
// will begin cropping the image
$left = 50;
$top = 50;
// This will be the final size of the image (e.g. how many pixels
// left and down we will be going)
$crop_width = 200;
$crop_height = 200;
// Resample the image
$canvas = imagecreatetruecolor($crop_width, $crop_height);
$current_image = imagecreatefromjpeg($filename);
imagecopy($canvas, $current_image, 0, 0, $left, $top, $current_width, $current_height);
imagejpeg($canvas, $filename, 100);
You define your crop width & height, and should be all set. Its not much more than a resize as you can see.
Reference: http://www.johnconde.net/blog/cropping-an-image-with-php-and-the-gd-library/

Related

issue when trying to copy image from remote location using php

I'm trying to copy an image from a remote location. I created a function that takes in the file name ($fname) and the path of the image ($remote_path). Currently I'm running PHP 5.3.28 with the following code:
function copy_remote_image($fname, $remote_path){
$thumbWidth = 612;
$folder = 'uploads/photos/';
$img = imagecreatefromjpeg( $remote_path );
if($img){
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// create a new temporary image
$tmp_img = imagecreatetruecolor( $new_width, $new_height );
// copy and resize old image into new image
imagecopyresampled( $tmp_img, $img, 0, 0, 0, 0, $new_width, $new_height, $width, $height );
// save thumbnail into a file
imagejpeg( $tmp_img, $folder.$fname,70 );
imagedestroy($tmp_img);
return true;
}else{
return false;
}
}
As of now the image is not copying and when I use var_dump on $img i get: resource(25) of type (gd)

Create a circle thumbnail from jpeg in PHP

Hi currently I built have function to create a thumbnail from an image and it does so, however I want it to be a circle thumbnail not a rectangle, how can I achieve this without using any external libraries just php built in methods? thank you
function createThumb( $imagepath, $thumbFile, $thumbWidth )
{
// load image and get image size
$img = imagecreatefromjpeg( "$imagepath" );
$width = imagesx( $img );
$height = imagesy( $img );
// calculate thumbnail size
$new_width = $thumbWidth;
$new_height = floor( $height * ( $thumbWidth / $width ) );
// 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 thumbnail into a file in the temp directory below script or somewhere
imagejpeg( $tmp_img, $thumbFile );
}
CSS is a better way to do it actually .
.class-name {
border-radius : 30px;
}

PHP temporary thumbnail

I'm not after saving an image, I just want to scale down an image by percentage and then display it on a webpage
I know I can use getimagesize to get the height width but how to scale correctly?
You can use a function like this .
Refer http://tutorialfeed.net/development/scale-an-image-using-php
function create_thumb( $imgSrc, $thumbnail_width, $thumbnail_height, $dest_src, $ext )
{
//getting the image dimensions
list( $width_orig, $height_orig ) = getimagesize( $imgSrc );
// Check if the images is a gif
if( $ext == 'gif' )
{
$myImage = imagecreatefromgif($imgSrc);
}
// Check if the image is a png
elseif( $ext == 'png' )
{
$myImage = imagecreatefrompng($imgSrc);
}
// Otherwise, file is jpeg
else
{
$myImage = imagecreatefromjpeg($imgSrc);
}
// Find the original ratio
$ratio_orig = $width_orig / $height_orig;
// Check whether to scale initially by height or by width
if( $thumbnail_width / $thumbnail_height > $ratio_orig )
{
$new_height = $thumbnail_width/$ratio_orig;
$new_width = $thumbnail_width;
}
else
{
$new_width = $thumbnail_height*$ratio_orig;
$new_height = $thumbnail_height;
}
$x_mid = $new_width / 2; //horizontal middle
$y_mid = $new_height / 2; //vertical middle
$process = imagecreatetruecolor( round( $new_width ), round( $new_height ) );
// Scale the image down and the reduce the other axis to create the thumbnail
imagecopyresampled($process, $myImage, 0, 0, 0, 0, $new_width, $new_height, $width_orig, $height_orig);
$thumb = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
imagecopyresampled($thumb, $process, 0, 0, ($x_mid-($thumbnail_width/2)), ($y_mid-($thumbnail_height/2)), $thumbnail_width, $thumbnail_height, $thumbnail_width, $thumbnail_height);
// Depending on the file extension, save the file
if( $ext == 'gif' )
{
imagegif( $thumb, $dest_src );
}
elseif( $ext == 'png' )
{
imagepng( $thumb, $dest_src );
}
else
{
imagejpeg( $thumb, $dest_src, 100 );
}
// Remove rubbish file data
imagedestroy($process);
imagedestroy($myImage);
// Return thumb ( success / fail )
return $thumb;
}
You can use the resizeInPourcent() method of ImageWorkshop (a library using the GD library): http://phpimageworkshop.com/doc/17/resizing.html
Ex:
<?php
$myImage->resizeInPourcent(50, 50); // Resize to get 50% width and height

PHP GD crop & scale image

I'm using jQuery's imgAreaSelect plugin in order to crop an image and save the thumbnail to use in cases where, for example, the ratio changes. Unfortunelly the results are far from what I would expect, and I can't get it right. The image gets resized as a whole instead of being cropped.
Here's the test example :
<?php
/***
*
* $_GET returned values
*
* x1 = 0
* x2 = 400
* y1 = 66
* y2 = 258
* w = 400
* h = 192
* folder = widethumb
* filename = IMG_4591.jpg
* scale = 48
*
* Original image properties
*
* width = 600px
* height = 900px
*
***/
define('DOCROOT', realpath(dirname(__FILE__)).DIRECTORY_SEPARATOR);
extract($_GET);
$fn = $filename;
$filename = DOCROOT.$filename;
list($width, $height) = getimagesize($filename);
$src = imagecreatefromjpeg($filename);
$dst = imagecreatetruecolor($w, $h);
imagecopyresampled($dst, $src, 0, 0, (int) $x1, (int) $y1, (int) $w, (int) $h, $width, $height);
header('Content-Type: image/jpeg');
imagejpeg($dst);
What am I mising here?
Cheers!
From PHP Documentation:
bool imagecopyresampled ( resource $dst_image , resource $src_image , int $dst_x , int $dst_y , int $src_x , int $src_y , int $dst_w , int $dst_h , int $src_w , int $src_h )
imagecopyresampled() copies a rectangular portion of one image to another image, smoothly interpolating pixel values so that, in particular, reducing the size of an image still retains a great deal of clarity.
In other words, imagecopyresampled() will take an 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).
So to get the result you are looking for, you need to avoid scaling. for that use:
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
// this can also be done but is less efficient (over 10 times slower)
imagecopyresampled($dst, $src, 0, 0, (int) $x1, (int) $y1, $w, $h, $w, $h);
Here we are are taking the same sized rectangle from source as we are putting it into destination image.
I have just tested it and it works just fine.
Update:
I have just tried again on my test server and it is working fine. I'm using following code:
$filename = "test.jpg";
extract($_GET);
$src = imagecreatefromjpeg($filename);
$dst = imagecreatetruecolor($w, $h);
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
// this is over 10 times slower, as we are only cropping we should use imagecopy
//imagecopyresampled($dst, $src, 0, 0, $x1, $y1, $w, $h, $w, $h);
header('Content-Type: image/jpeg');
imagejpeg($dst);
And I'm calling it like this:
http://localserver/test/gd_crop.php?x1=906&y1=267&w=501&h=355
Performance Update
As we are not resizing we can simply use imagecopy. Performance of 3 functions as i have measured is given below.
imagecopyresampled 69ms
imagecopyresized 5.5ms
imagecopy 4.5ms
So there is an order of 10 speed difference between resampled and the two other functions.
I have finally come up with following line in place of imagecopyresampled function, try it, I have also updated the above code listing:
imagecopy($dst, $src, 0, 0, $x1, $y1, $w, $h);
Use the WideImage library instead.
This is my own cropping function:
function createThumbnail($file, $cropX, $cropY, $cropWidth, $cropHeight, $desiredWidth, $desiredHeight, $shrink = false)
{
if(file_exists(MPS_ROOT_PATH . "$file") && $cropWidth && $cropHeight)
{
$source_path = MPS_ROOT_PATH . $file;
list( $source_width, $source_height, $source_type ) = getimagesize( $source_path );
switch ( $source_type )
{
case IMAGETYPE_GIF:
$source_gdim = imagecreatefromgif( $source_path );
break;
case IMAGETYPE_JPEG:
$source_gdim = imagecreatefromjpeg( $source_path );
break;
case IMAGETYPE_PNG:
$source_gdim = imagecreatefrompng( $source_path );
break;
default:
return false;
}
if(!$desiredWidth)
{
// Desired width not set, computing new width based on original
// image's aspect ratio...
$desiredWidth = $cropWidth * ($desiredHeight / $cropHeight);
}
if(!$desiredHeight)
{
// Desired height not set, computing new height based on original
// image's aspect ratio
$desiredHeight = $cropHeight * ($desiredWidth / $cropWidth);
}
if(!$desiredWidth || !$desiredHeight)
{
// Desired height or width not set.
// Halting image processing and returning file
return $file;
}
$source_aspect_ratio = $cropWidth / $cropHeight;
$desired_aspect_ratio = $desiredWidth / $desiredHeight;
if($shrink)
{
// Shrink to fit flag set. Inverting computations to make image fit
// within the desired dimensions...
if($source_aspect_ratio > $desired_aspect_ratio)
{
// Source image is wider than desired aspect ratio,
// setting thumbnail width to the desired width and the height
// will be computed based on the original image's aspect ratio
$temp_width = $desiredWidth;
$temp_height = (int) ($desiredWidth / $source_aspect_ratio);
}
else
{
// Source image is taller than desired aspect ratio,
// setting thumbnail height to the desired height and the width
// will be computed based on the original image's aspect ratio
$temp_height = $desiredHeight;
$temp_width = (int) ($desiredHeight * $source_aspect_ratio);
}
}
// shrink to fit not set
else
{
if($source_aspect_ratio > $desired_aspect_ratio)
{
// Source image is wider than desired aspect ratio,
// setting thumbnail height to the desired height to fill the
// desired aspect ratio and the width will be computed based on
// the original image's aspect ratio
$temp_height = $desiredHeight;
$temp_width = (int) ($desiredHeight * $source_aspect_ratio);
}
else
{
// Source image is taller than desired aspect ratio,
// setting thumbnail width to the desired width to fill the
// desired aspect ratio and the width will be computed based on
// the original image's aspect ratio");
$temp_width = $desiredWidth;
$temp_height = (int) ($desiredWidth / $source_aspect_ratio);
}
}
$temp_gdim = imagecreatetruecolor($temp_width, $temp_height);
// Copying a $cropWidth x $cropHeight image from the source
// file at ($cropX, $cropY) and resampling it to fit the temporary
// $temp_width x $temp_height thumbnail at (0, 0)
imagecopyresampled(
$temp_gdim,
$source_gdim,
0, 0,
$cropX, $cropY,
$temp_width, $temp_height,
$cropWidth, $cropHeight
);
$x0 = ($desiredWidth - $temp_width) / 2;
$y0 = ($desiredHeight - $temp_height) / 2;
// Positioning the temporary $temp_width x $temp_height thumbnail in
// the center of the final $desiredWidth x $desiredHeight thumbnail...
// Creating final thumbnail canvas at $desiredWidth x $desiredHeight
$desired_gdim = imagecreatetruecolor($desiredWidth, $desiredHeight);
$white = imagecolorallocate($desired_gdim, 255, 255, 255);
imagefill($desired_gdim, 0, 0, $white);
// Filling final thumbnail canvas with white
// Copying a $temp_width x $temp_height image from the temporary
// thumbnail at (0, 0) and placing it in the final
// thumbnail at ($x0, $y0)
imagecopy(
$desired_gdim,
$temp_gdim,
$x0, $y0,
0, 0,
$temp_width, $temp_height
);
$pathInfo = pathinfo($file);
$thumbFile = "images/thumbs/thumb_" . basename($pathInfo["filename"]) . ".jpg";
if(imagejpeg($desired_gdim, MPS_ROOT_PATH . $thumbFile, 80))
{
return $thumbFile;
}
else
{
return 1;
}
}
else
{
echo "Image File Does not exist or Invalid crop parameters!";
return false;
}
}
Why don't you look into using imagemagik; it's great for image manipulation and cropping is just a simple case of using cropImage($width, $height, $x, $y);
Here's a function that you can pass the destination dimension to and will scale and crop from the center, maintain aspect ratio, and will scale up. This is easy to implement with the picture element for responsive design. If you change your destination dimensions, just delete the outputted files and this will recreate the images in their absence.
<?php
function scaleCrop($src, $dest, $destW, $destH, $anchor){
if(!file_exists($dest) && is_file($src) && is_readable($src)){
$srcSize = getimagesize($src);
$srcW = $srcSize[0];
$srcH = $srcSize[1];
$srcRatio = $srcW / $srcH;
$destRatio = $destW / $destH;
$img = (imagecreatefromjpeg($src));
$imgNew = imagecreatetruecolor($destW, $destH);
if ($srcRatio < $destRatio){
$scale = $srcW / $destW;
}
elseif($srcRatio >= $destRatio){
$scale = $srcH / $destH;
}
$srcX = ($srcW - ($destW * $scale)) / 2;
if($anchor = 'middle'){
$srcY = ($srcH - ($destH * $scale)) / 2;
}
elseif($anchor = 'top'){
$srcY = 0;
}
elseif($anchor = 'bottom'){
$srcY = $srcH - ($destH * $scale);
}
if($srcX < 0){$srcX = 0;};
if($srcY < 0){$srcY = 0;};
imagecopyresampled($imgNew, $img, 0, 0, $srcX, $srcY, $destW, $destH, $destW * $scale, $destH * $scale);
imagejpeg($imgNew, $dest, 70);
imagedestroy($img);
imagedestroy($imgNew);
}
return $dest;
}
?>
<img src="<?php echo scaleCrop('srcfolder/srcfile.jpg', 'destfolder/destfile.jpg', 320, 240, 'top'); ?>">

Using PHP to create an image and add a logo to it

What I am trying to do is speed up some of the time building websites since we have such a large work load. We tend to be doing the same things over and over, and for these Night Drop forms we have a small image preview below. When clicked on it will open up the PDF, but I was wondering if there is a way to automate this so the image preview will automatically be created and just take the logo and re-size it and put it on the top like below.
Is this possible? So it would start with the blank form on the left, and then take the logo.png file from the website and re-size it to the correct dimensions and put it in the top center like on the second image.
Sorry if this is a stupid question, just would be awesome if it could work!
Thanks :-)
I got it to work! Here is the code for anyone interested.
<?php
function resize($img, $w, $h, $newfilename) {
//Check if GD extension is loaded
if (!extension_loaded('gd') && !extension_loaded('gd2')) {
trigger_error("GD is not loaded", E_USER_WARNING);
return false;
}
//Get Image size info
$imgInfo = getimagesize($img);
switch ($imgInfo[2]) {
case 1: $im = imagecreatefromgif($img); break;
case 2: $im = imagecreatefromjpeg($img); break;
case 3: $im = imagecreatefrompng($img); break;
default: trigger_error('Unsupported filetype!', E_USER_WARNING); break;
}
//If image dimension is smaller, do not resize
if ($imgInfo[0] <= $w && $imgInfo[1] <= $h) {
$nHeight = $imgInfo[1];
$nWidth = $imgInfo[0];
}else{
//yeah, resize it, but keep it proportional
if ($w/$imgInfo[0] > $h/$imgInfo[1]) {
$nWidth = $w;
$nHeight = $imgInfo[1]*($w/$imgInfo[0]);
}else{
$nWidth = $imgInfo[0]*($h/$imgInfo[1]);
$nHeight = $h;
}
}
$nWidth = round($nWidth);
$nHeight = round($nHeight);
$newImg = imagecreatetruecolor($nWidth, $nHeight);
/* Check if this image is PNG or GIF, then set if Transparent*/
if(($imgInfo[2] == 1) OR ($imgInfo[2]==3)){
imagealphablending($newImg, false);
imagesavealpha($newImg,true);
$transparent = imagecolorallocatealpha($newImg, 255, 255, 255, 127);
imagefilledrectangle($newImg, 0, 0, $nWidth, $nHeight, $transparent);
}
imagecopyresampled($newImg, $im, 0, 0, 0, 0, $nWidth, $nHeight, $imgInfo[0], $imgInfo[1]);
//Generate the file, and rename it to $newfilename
switch ($imgInfo[2]) {
case 1: imagegif($newImg,$newfilename); break;
case 2: imagejpeg($newImg,$newfilename); break;
case 3: imagepng($newImg,$newfilename); break;
default: trigger_error('Failed resize image!', E_USER_WARNING); break;
}
return $newfilename;
}
$img = "images/logo.png"; // File image location
$newfilename = "images/dropoff_preview.png"; // New file name for thumb
$w = 45;
$h = 45;
$thumbnail = resize($img, $w, $h, $newfilename);
$image = #$HTTP_GET_VARS['image']; // Useful if using in an img tag to call images
$image = str_replace(array("/", ".."), "", $image); // Prevent abuse
$overlay = $thumbnail;
$dir = '';
// A default image for the demo...remove if you wish.
if ($image == NULL) {
$image = 'images/dropoff_blank.jpg';
}
// Find if image exists
if (!file_exists($dir . $image)) {
die("Image does not exist.");
}
// Set offset from bottom-right corner
$w_offset = 57;
$h_offset = 230;
$extension = strtolower(substr($image, strrpos($image, ".") + 1));
// Load image from file
switch ($extension)
{
case 'jpg':
$background = imagecreatefromjpeg($dir . $image);
break;
case 'jpeg':
$background = imagecreatefromjpeg($dir . $image);
break;
case 'png':
$background = imagecreatefrompng($dir . $image);
break;
case 'gif':
$background = imagecreatefromgif($dir . $image);
break;
default:
die("Image is of unsupported type.");
}
// Find base image size
$swidth = imagesx($background);
$sheight = imagesy($background);
// Turn on alpha blending
imagealphablending($background, true);
// Create overlay image
$overlay = imagecreatefrompng($dir . $overlay);
// Get the size of overlay
$owidth = imagesx($overlay);
$oheight = imagesy($overlay);
// Overlay watermark
imagecopy($background, $overlay, $swidth - $owidth - $w_offset, $sheight - $oheight - $h_offset, 0, 0, $owidth, $oheight);
// Output header and final image
header("Content-type: image/jpeg");
header("Content-Disposition: filename=" . $image);
imagejpeg($background);
// Destroy the images
imagedestroy($background);
imagedestroy($overlay);
function doResizeAndWatermark () {
$image = 'myImage.jpg';
$watermarkImage = 'logo.png';
$x = 10;
$y = 10;
$resizeWidth = '100';
$resizeHeight = '200';
$imagesize = getimagesize ( $image );
$newImage = $image;
if ( ! copy ( $image, $this->newImage ) )
die ( 'Copy Image Failed' );
$image = imagecreatefromjpeg ( $image );
$newImage = imagecreatetruecolor ( $imagesize [ 0 ], $imagesize [ 1 ] );
if ( ! imagecopyresampled ( $newImage, $image, 0, 0, 0, 0, $resizeWidth, $resizeHeight, $imagesize [ 0 ], $imagesize [ 1 ] ) ) {
die ( 'Resizing Image Faild' );
}
$tmprslt = getimagesize ( $watermarkImage );
$watermarkImageWidth = $tmprslt [ 0 ];
$watermarkImageHeight = $tmprslt [ 1 ];
$watermarkImage = imagecreatefrompng ( $watermarkImage );
if ( ! imagecopyresampled ( $image, $watermarkImage, $x, $y, 0, 0, $watermarkImageWidth, $watermarkImageWidth, $watermarkImageWidth, $watermarkImageHeight ) )
die ( 'Watermark Copy Image Failed' );
imagejpeg ( $newImage, $image, 85 );
}

Categories