i've tried to make a image gallery, but I'm stuck on shrinking script. I have it made as function. Original input $_FILES['image'] is substitued on $original.
I'm pretty sure this part is OK, but I'm adding it for better orientation.
$orig_udaje = getimagesize($original['tmp_name']);
$orig_sirka = $orig_udaje[0]; //original width
$orig_vyska = $orig_udaje[1]; //original height
$orig_typ = $orig_udaje[2]; //type of original image
$div_size = 150; //size of image div = size of future thumbnail's smaller side
// choosing smaller side & defining resizing scale
if ($orig_sirka>$orig_vyska)
{
$mira = $orig_vyska / $div_size;
}
else
{
$mira = $orig_sirka / $div_size;
}
$nahled_sirka = $orig_sirka / $mira;
$nahled_vyska = $orig_vyska / $mira;
I think the troubled part is somewhere below this text.
$nahled_cache = imagecreatetruecolor($nahled_sirka, $nahled_vyska);
imagecolortransparent($nahled_cache, "0, 0, 0");
if ($orig_typ == "image/jpeg")
{
$nahled_tvorba = imagecreatefromjpeg($original['tmp_name']);
imagecopyresampled($nahled_cache, $nahled_tvorba, 0, 0, 0, 0, $nahled_sirka, $nahled_vyska, $orig_sirka, $orig_vyska);
imagejpeg($nahled_cache, "/data/images/gallery/thumbs/output.jpg");
imagejpeg($original['tmp_name'], "/data/images/gallery/originals/output.jpg");
unlink($original['tmp_name']);
}
if ($orig_typ == "image/png")
{
$obrazek_tvorba = imagecreatefrompng($original['tmp_name']);
imagecopyresampled($nahled_cache, $nahled_tvorba, 0, 0, 0, 0, $nahled_sirka, $nahled_vyska, $orig_sirka, $orig_vyska);
imagepng($nahled_cache, "/data/images/gallery/thumbs/output.png");
imagepng($original['tmp_name'], "/data/images/gallery/originals/output.png");
unlink($original['tmp_name']);
}
Thank you for your advice.
I suggest you not to write the code, that already written so many times...
Try to use some open source classes. Like this one. The class is easy and lightweight, and have pretty good documentation.
The usage is simple:
// *** Include the class
include("resize-class.php");
// *** 1) Initialize / load image
$resizeObj = new resize('sample.jpg');
// *** 2) Resize image (options: exact, portrait, landscape, auto, crop)
$resizeObj -> resizeImage(150, 100, 'crop');
// *** 3) Save image
$resizeObj -> saveImage('sample-resized.gif', 100);
You can use 'auto' option instead of 'crop', and provide max width and height. This mean's, that the image resolution will be generated based on the maximum properties you provided, and also, based on image orientation. Try it ;)
Related
I’m creating an uploader that can upload jpg, giff and png images. Then converts them all too transparent PNG’s and then crops the image based on crop parameters send from client side. The crop can even supply negative axis coordinates, meaning the image is being cropped beyond image dimensions.
To ensure all supported formats can have transparency I first recreate the image into a transparent png, and this is working well.
//GET WIDTH AND HIEGHT OF UPLOADED JPG
list($imageWidth,$imageHeight)= getimagesize($originalDirectory.$file_name);
$image = imagecreatefromjpeg($originalDirectory.$file_name);
//CREATE NEW IMAGE BASED ON WIDTH AND HEIGHT OF SROUCE IMAGE
$bg = imagecreatetruecolor($imageWidth, $imageHeight);
//TRANSPARENCY SETTINGS FOR BOTH DESTINATION AND SOURCE IMAGES
$transparent2 = imagecolorallocatealpha($bg, 0, 0, 0, 127);
$transparent = imagecolorallocatealpha($image, 0,128,255,50); //ONLY TO ENSURE TRANSPARENCY IS WORKING
//SAVE TRANSPARENCY AMD FILL DESTINATION IMAGE
imagealphablending( $bg, false );
imagesavealpha($bg, true);
imagefill($bg, 0, 0, $transparent2);
//SAVE TRANSPARENCY AMD FILL SOURCE IMAGE
imagealphablending( $image, false );
imagesavealpha($image, true);
imagefill($image, 0, 0, $transparent); //ONLY TO ENSURE TRANSPARENCY IS WORKING
//CREATE AND SAVE AS PNG FILE WITH TRANSPARENCY
imagecopy($bg, $image, 0, 0, 0, 0, $imageWidth,$imageHeight);
header('Content-type: image/png');
imagepng($bg, $originalDirectory.$jpgFile);
imagedestroy($bg);
After the new png is created I use it to then only crop the image according to the parameters passed through from the client side scripting.
//GET NEWLY CREATED PNG
$src = imagecreatefrompng($originalSRC);
// NOT SURE IF NECESSARY BUT HAS NO EFFECT ON FINAL RESULT REGGARDLESS OF ANY SETTINGS DONE
imagealphablending( $image, false );
imagesavealpha($image, true);
//DEFINE DESTINATION CROPPED FILE
$thumbHighFilename = $thumbHighDirectory.'test.png';
//CREATE NEW IMAGE BASED ON FINAL CROP SIZE
$tmp = imagecreatetruecolor($cropWidth, $cropHeight);
//ENSURE DESTINATION HAS TRANSPARENT BACKGROUND
$transparent2 = imagecolorallocatealpha($tmp, 0, 0, 0, 127);
imagealphablending( $tmp, false );
imagesavealpha($tmp, true);
imagefill($tmp, 0, 0, $transparent2);
/* -------------------------------------------------
PROBLEM HERE
When I try to merge the two with the crop paramaters
send from client side. All transparencies work, except
where crop X and Y axis exceeds source image paramaters.
Currently 50px offset on destination image is to verify
transparency works.
The source coordinates are based on image not crop area.
Tried with both imagecopyresized & imagecopyresampled
-------------------------------------------------*/
imagecopyresized($tmp, $src, -50,-50, $xAxis,$yAxis,$cropWidth, $cropHeight, $pW, $pH);
//SAVE FINAL IMAGE
header('Content-type: image/png');
imagepng($tmp, $thumbHighFilename);
imagedestroy($tmp);
This is where the source and destination images still has there transparency; however the negative coordinates creates a black background around the source image. How can I get that to be transparent?
While I found a lot about transparencies, nothing has been a proper solution. For example imagefill afterwards will not work as source could use 100% black around the edges and will make that also transparent then, which it shouldn’t.
CLIENT SIDE CROP EXAMPLE WITH INDICATIONS
CURRENT FINAL IMAGE RESULT WITH ADDED INDICATIONS
From what I could find it seems that there is no way for the GD imagecopyresized and imagecopyresampled to inherit the default backgrounds of the images it is cropping. Thus it keeps adding the default black background to the source image.
The biggest problem I’ve had was actually the crop container being responsive, thus very difficult to determine crop parameters.
To get around the problem I asked my frontend developer to send me more parameters from the crop. Below are all parameters now being passed to php, and the variables in php that are linked to the parameters received:
$xAxisCropper & $yAxisCropper – The variables get the X and Y
coordinates of the container not the image being cropped.
$pW & $pH – Defines the width and height of the crop box.
$containerWidth & $containerheight – As the container is responsive
getting the height and width helps understand what size the
coordinates where calculated on.
$imResizeHeight & $imResizeWidth – Since the images in the container
are always set to be contained within the container, it was important
to get the width and height into which the image is being resized by
the CSS. Giving understanding of what is happening with the image
within the responsive container.
$originalWidth & $originalHeight – Defines the original size of the
image and could either be passed to php or retrieved from the
original image uploaded to the server.
With these parameters I could now recreate the container with the image in the centre, and crop the newly created image. Before I crop it’s important to get the right scaling of the image for the crop, in order to ensure the best quality image is cropped and not compressed before cropping.
To do this I started by determining if the image in the container is being scaled up or down within the container. If scaled up image needs to be scaled to container size, if scaled down the container needs to be increased to have the image fit in the container. Below is the code that currently determines this, and changes the necessary parameters accordingly:
//IF CSS CONTAIN RESIZES HEIGHT EQUAL TO CROP CONTAINER HEIGHT
if($imResizeHeight == $containerheight){
//IF IMAGE SIZE WAS INCREASED
if($imResizeHeight>$originalHeight){
//DEFINE NEW IMAGE SIZE TO SCALE TO CONTAINER
$new_height = $imResizeHeight;
$new_width = $originalWidth * ($new_height / $originalHeight);
$scale = 'image'; //DEFINE WHAT IS BEING INCREASED
//ESLSE INCREASE CONTAINER TO IMAGE HEIGHT DIMENSIONS
}else{
//RECALCULATE WIDTH & HEIGHT OF CONTAINER
$newContainerWidth = $containerWidth * ($originalHeight / $containerheight);
$newContainerheight = $originalHeight;
$scale = 'container'; //DEFINE WHAT IS BEING INCREASED
}
//IF CSS CONTAIN RESIZES WIDTH EQUAL TO CROP CONTAINER WIDTH
}elseif($imResizeWidth == $containerWidth) {
//IF IMAGE SIZE WAS INCREASED
if($imResizeWidth>$originalWidth){
//DEFINE NEW IMAGE SIZE TO SCALE TO CONTAINER
$new_width = $imResizeWidth;
$new_height = $originalHeight * ($new_width / $originalWidth);
$scale = 'image'; //DEFINE WHAT IS BEING INCREASED
//ESLSE INCREASE CONTAINER TO IMAGE WIDTH DIMENSIONS
}else{
//RECALCULATE WIDTH & HEIGHT OF CONTAINER
$newContainerheight = $containerheight * ($originalWidth / $containerWidth);
$newContainerWidth = $originalWidth;
$scale = 'container'; //DEFINE WHAT IS BEING INCREASED
}
}
//IF IMAGE WAS INCREASED
if($scale=='image'){
//SCALE IMAGE
$src = imagescale ( $src , $new_width , $new_height, IMG_BILINEAR_FIXED);
imagepng($src,$originalSRC,0);
//ADD CHANGES TO VARIABLES USED IN CROP
$pH = $pH * ($new_height / $originalHeight);
$pW = max(0, round($pW * ($new_width / $originalWidth)));
$originalWidth = $new_width;
$originalHeight = $new_height;
$newContainerWidth = $containerWidth;
$newContainerheight = $containerheight;
//ELSE CONTAINER WAS INCREASED
}else {
//RECALCULATE COORDINATES OF CONTAINER
$yAxisCropper = max(0, round($yAxisCropper * ($newContainerheight / $containerheight)));
$xAxisCropper = max(0, round($xAxisCropper * ($newContainerWidth / $containerWidth)));
}
Once the parameters have been redefined according to the scaling, I then create the transparent background according to the container size and add the image in the centre. Thus creating a proper version of the crop container as an image, below the code for creating the new image:
//CALCULATE CENTRE OF NEW CONTAINER
$centreX = max(0, round(($newContainerWidth-$originalWidth)/2));
$centreY = max(0, round(($newContainerheight-$originalHeight)/2));
//CREATE NEW IMAGE BASED ON WIDTH AND HEIGHT OF SROUCE IMAGE
$bg = imagecreatetruecolor($newContainerWidth, $newContainerheight);
//SAVE TRANSPARENCY AMD FILL DESTINATION IMAGE
$transparent = imagecolorallocatealpha($bg, 0,0,0,127);
imagealphablending( $bg, false);
imagesavealpha($bg, true);
imagefill($bg, 0, 0, $transparent);
//CREATE AND SAVE AS PNG FILE WITH TRANSPARENCY
imagecopy($bg, $src, $centreX, $centreY, 0, 0, $originalWidth,$originalHeight);
header('Content-type: image/png');
imagepng($bg, $originalSRC, 0);
imagedestroy($bg);
The result till thus far:
It is only at this point that I send the new image to be cropped according to the specified width and height. Code below:
$src = imagecreatefrompng($originalSRC);
$thumbHighFilename = $thumbHighDirectory.$new_image;
$tmp = imagecreatetruecolor($cropWidth, $cropHeight);
$transparent2 = imagecolorallocatealpha($tmp, 0, 0, 0, 127);
imagealphablending( $tmp, false );
imagesavealpha($tmp, true);
imagefill($tmp, 0, 0, $transparent2);
imagealphablending( $tmp, false );
imagesavealpha($tmp, true);
imagecopyresampled($tmp, $src, 0,0, $xAxisCropper,$yAxisCropper,$cropWidth, $cropHeight, $pW, $pH);
header('Content-type: image/png');
imagepng($tmp, $thumbHighFilename, 2);
Final result cropped 400x300
This has been the only way so far that I’ve managed to solve the problem. Code could probably still be optimised, but if someone has a more optimal solution please share.
I also wish to thank my frontend developer Salem for helping me to solve this irritating issue.
I also did have this annoying black Background Problem with png Files and the imagecropauto Function.
After "some" Tests, i have found a Solution as it seems. At least it works for me.
Here is my mofified Code:
$im=imagecreatefrompng("yourpicture.png");
$cropped=imagecropauto($im, IMG_CROP_SIDES);
imagesavealpha($cropped,true);
if($cropped !==false) {
imagedestroy($im);
$im=$cropped;
}
imagepng($im, "yourpicturecropped.png");
imagedestroy($im);
This question already has answers here:
imagecreatefromjpeg and similar functions are not working in PHP
(14 answers)
Closed 8 years ago.
I need to resize a picture to a fixed size. But it doesn't work and have error, what do i do?
ONLINE DEMO: http://codepad.org/3OrIHfoy
ERROR:
Fatal error: Call to undefined function imagecreatefromjpeg() on line
58
PHP:
<?php
function thumbnail_box($img, $box_w, $box_h) {
//create the image, of the required size
$new = imagecreatetruecolor($box_w, $box_h);
if($new === false) {
//creation failed -- probably not enough memory
return null;
}
//Fill the image with a light grey color
//(this will be visible in the padding around the image,
//if the aspect ratios of the image and the thumbnail do not match)
//Replace this with any color you want, or comment it out for black.
//I used grey for testing =)
$fill = imagecolorallocate($new, 200, 200, 205);
imagefill($new, 0, 0, $fill);
//compute resize ratio
$hratio = $box_h / imagesy($img);
$wratio = $box_w / imagesx($img);
$ratio = min($hratio, $wratio);
//if the source is smaller than the thumbnail size,
//don't resize -- add a margin instead
//(that is, dont magnify images)
if($ratio > 1.0)
$ratio = 1.0;
//compute sizes
$sy = floor(imagesy($img) * $ratio);
$sx = floor(imagesx($img) * $ratio);
//compute margins
//Using these margins centers the image in the thumbnail.
//If you always want the image to the top left,
//set both of these to 0
$m_y = floor(($box_h - $sy) / 2);
$m_x = floor(($box_w - $sx) / 2);
//Copy the image data, and resample
//
//If you want a fast and ugly thumbnail,
//replace imagecopyresampled with imagecopyresized
if(!imagecopyresampled($new, $img,
$m_x, $m_y, //dest x, y (margins)
0, 0, //src x, y (0,0 means top left)
$sx, $sy,//dest w, h (resample to this size (computed above)
imagesx($img), imagesy($img)) //src w, h (the full size of the original)
) {
//copy failed
imagedestroy($new);
return null;
}
//copy successful
return $new;
}
$i = imagecreatefromjpeg("http://techstroke.com/wp-content/uploads/2008/12/image2.png");
$thumb = thumbnail_box($i, 210, 150);
imagedestroy($i);
if(is_null($thumb)) {
/* image creation or copying failed */
header('HTTP/1.1 500 Internal Server Error');
exit();
}
header('Content-Type: image/jpeg');
imagejpeg($thumb);
that error...
Fatal error: Call to undefined function imagecreatefromjpeg() on line 58
imagecreatefromjpeg() is not callable because it does not exist. This means that the GD library has yet to be installed on your system.
here are the installation notes. you'll need them to get everything going. since you snagged that php function off the internet, it should work okay once you get the GD library installed.
I am using imagine library to create thumbnails for images. It is as simple as this.
$size = new \Imagine\Image\Box(240, 180);
$imagine->open($source_path)->thumbnail($size, 'inset')->save($target_path);
the library provides two modes : inset and outbound. in inset mode the image is resized down but it does not fill the thumbnail size. So I need to pad it to fill the target size. Is there an easy way to do this using library functions ?
You have to crop your image if you don't want to "scale" thumbnails to fit. For cropping, you have to find exact starting points and it requires a little bit effort.
Writing a custom method to find exact cropping point, resize and return the new image is good idea. Imagine is really good library, it provides all methods we need.
Steps to follow:
Get the original image's dimensions using getSize()
Detect orientation of the image by comparing width and height.
Then find the exact crop point by orientation which you need to fit your new thumbnail without "scaling":
If it's landscape, find target width by using target box's width
Otherwise by using height.
Resize image using THUMBNAIL_OUTBOUND and create a "little big thumbnail".
Crop resized image using the cropping points which you find before.
Return the image instance.
Pseudo code:
function resizeToFit( $targetWidth, $targetHeight, $sourceFilename )
{
// Box is Imagine Box instance
// Point is Imagine Point instance
$target = new Box($targetWidth, $targetHeight );
$originalImage = imagine->open( $sourceFilename );
$orgSize = $originalImage->getSize();
if ($orgSize->width > $orgSize->height) {
// Landscaped.. We need to crop image by horizontally
$w = $orgSize->width * ( $target->height / $orgSize->height );
$h = $target->height;
$cropBy = new Point( ( max ( $w - $target->width, 0 ) ) / 2, 0);
} else {
// Portrait..
$w = $target->width; // Use target box's width and crop vertically
$h = $orgSize->height * ( $target->width / $orgSize->width );
$cropBy = new Point( 0, ( max( $h - $target->height , 0 ) ) / 2);
}
$tempBox = Box($w, $h);
$img = $originalImage->thumbnail($tempBox, ImageInterface::THUMBNAIL_OUTBOUND);
// Here is the magic..
return $img->crop($cropBy, $target); // Return "ready to save" final image instance
}
I have managed to pad thumbnails with following function.
function pad(\Imagine\Gd\Imagine $img, \Imagine\Image\Box $size, $fcolor='#000', $ftransparency = 100)
{
$tsize = $img->getSize();
$x = $y = 0;
if ($size->getWidth() > $tsize->getWidth()) {
$x = round(($size->getWidth() - $tsize->getWidth()) / 2);
} elseif ($size->getHeight() > $tsize->getHeight()) {
$y = round(($size->getHeight() - $tsize->getHeight()) / 2);
}
$pasteto = new \Imagine\Image\Point($x, $y);
$imagine = new \Imagine\Gd\Imagine();
$color = new \Imagine\Image\Color($fcolor, $ftransparency);
$image = $imagine->create($size, $color);
$image->paste($img, $pasteto);
return $image;
}
foozy, thanks for your comment, it helped me a lot!
But for me better worked this:
$img->resize($tempBox);
Instead of this:
$img = $originalImage->thumbnail($tempBox, ImageInterface::THUMBNAIL_OUTBOUND);
Maybe it will help somebody.
Using the following script I´m getting over-compressed images on the front end. They appear fine on the server, but the imagesize.php seems to be destroying the end result. Here is a visual of the issue (ignore the slight difference in size on this image, that's my bad alignment) http://puu.sh/38VaP.png. Any ideas? Here is the script...
<?php
// Get the File path for the image
$imagedir = '../../imgs';
$imagename = $_GET["file"];
$sImagePath = "$imagedir/$imagename";
// If you want exact dimensions, you
// will pass 'width' and 'height'
$iThumbnailWidth = (int)$_GET['width'];
$iThumbnailHeight = (int)$_GET['height'];
// If you want proportional thumbnails,
// you will pass 'maxw' and 'maxh'
$iMaxWidth = (int)$_GET["maxw"];
$iMaxHeight = (int)$_GET["maxh"];
// Based on the above we can tell which
// type of resizing our script must do
if ($iMaxWidth && $iMaxHeight) $sType = 'scale';
else if ($iThumbnailWidth && $iThumbnailHeight) $sType = 'exact';
// The 'scale' type will make the image
// smaller but keep the same dimensions
// The 'exact' type will make the thumbnail
// exactly the width and height you choose
// To start off, we will create a copy
// of our original image in $img
$img = NULL;
// At this point, we need to know the
// format of the image
// Based on that, we can create a new
// image using these functions:
// - imagecreatefromjpeg
// - imagecreatefrompng
// - imagecreatefromgif
//$sExtension = strtolower(end(explode('.', $sImagePath)));
$explodedImagePath = explode('.',$sImagePath);
$sExtension = strtolower(end($explodedImagePath));
if ($sExtension == 'jpg' || $sExtension == 'jpeg') {
$img = #imagecreatefromjpeg($sImagePath)
or die("Cannot create new JPEG image");
} else if ($sExtension == 'png') {
$img = #imagecreatefrompng($sImagePath)
or die("Cannot create new PNG image");
} else if ($sExtension == 'gif') {
$img = #imagecreatefromgif($sImagePath)
or die("Cannot create new GIF image");
}
// If the image has been created, we may proceed
// to the next step
if ($img) {
// We now need to decide how to resize the image
// If we chose to scale down the image, we will
// need to get the original image propertions
$iOrigWidth = imagesx($img);
$iOrigHeight = imagesy($img);
if ($sType == 'scale') {
// Get scale ratio
$fScale = min($iMaxWidth/$iOrigWidth,
$iMaxHeight/$iOrigHeight);
// To explain how this works, say the original
// dimensions were 200x100 and our max width
// and height for a thumbnail is 50 pixels.
// We would do $iMaxWidth/$iOrigWidth
// (50/200) = 0.25
// And $iMaxHeight/$iOrigHeight
// (50/100) = 0.5
// We then use the min() function
// to find the lowest value.
// In this case, 0.25 is the lowest so that
// is our scale. The thumbnail must be
// 1/4th (0.25) of the original image
if ($fScale < 1) {
// We must only run the code below
// if the scale is lower than 1
// If it isn't, this means that
// the thumbnail we want is actually
// bigger than the original image
// Calculate the new height and width
// based on the scale
$iNewWidth = floor($fScale*$iOrigWidth);
$iNewHeight = floor($fScale*$iOrigHeight);
// Create a new temporary image using the
// imagecreatetruecolor function
$tmpimg = imagecreatetruecolor($iNewWidth,
$iNewHeight);
// The function below copies the original
// image and re-samples it into the new one
// using the new width and height
imagecopyresampled($tmpimg, $img, 0, 0, 0, 0,
$iNewWidth, $iNewHeight, $iOrigWidth, $iOrigHeight);
// Finally, we simply destroy the $img file
// which contained our original image
// so we can replace with the new thumbnail
imagedestroy($img);
$img = $tmpimg;
}
} else if ($sType == "exact") {
// Get scale ratio
$fScale = max($iThumbnailWidth/$iOrigWidth,
$iThumbnailHeight/$iOrigHeight);
// This works similarly to other one but
// rather than the lowest value, we need
// the highest. For example, if the
// dimensions were 200x100 and our thumbnail
// had to be 50x50, we would calculate:
// $iThumbnailWidth/$iOrigWidth
// (50/200) = 0.25
// And $iThumbnailHeight/$iOrigHeight
// (50/100) = 0.5
// We then use the max() function
// to find the highest value.
// In this case, 0.5 is the highest so that
// is our scale. This is the first step of
// the image manipulation. Once we scale
// the image down to 0.5, it will have the
// dimensions of 100x50. At this point,
// we will need to crop the image, leaving
// the height identical but halving
// the width to 50
if ($fScale < 1) {
// Calculate the new height and width
// based on the scale
$iNewWidth = floor($fScale*$iOrigWidth);
$iNewHeight = floor($fScale*$iOrigHeight);
// Create a new temporary image using the
// imagecreatetruecolor function
$tmpimg = imagecreatetruecolor($iNewWidth,
$iNewHeight);
$tmp2img = imagecreatetruecolor($iThumbnailWidth,
$iThumbnailHeight);
// The function below copies the original
// image and re-samples it into the new one
// using the new width and height
imagecopyresampled($tmpimg, $img, 0, 0, 0, 0,
$iNewWidth, $iNewHeight, $iOrigWidth, $iOrigHeight);
// Our $tmpimg will now have the scaled down
// image. The next step is cropping the picture to
// make sure it's exactly the size of the thumbnail
// The following logic choose how the image
// will be cropped. Using the previous example, it
// needs to take a 50x50 block from the original
// image and copy it over to the new thumbnail
// Since we want to copy the exact center of the
// scaled down image, we need to find out the x
// axis and y axis. To do so, say the scaled down
// image now has a width of 100px but we want it
// to be only 50px
// Somehow, we need to select between the 25th and
// 75th pixel to copy the middle.
// To find this value we do:
// ($iNewWidth/2)-($iThumbnailWidth/2)
// ( 100px / 2 ) - (50px / 2)
// ( 50px ) - ( 25px )
// = 25px
if ($iNewWidth == $iThumbnailWidth) {
$yAxis = ($iNewHeight/2)-
($iThumbnailHeight/2);
$xAxis = 0;
} else if ($iNewHeight == $iThumbnailHeight) {
$yAxis = 0;
$xAxis = ($iNewWidth/2)-
($iThumbnailWidth/2);
}
// We now have to resample the new image using the
// new dimensions are axis values.
imagecopyresampled($tmp2img, $tmpimg, 0, 0,
$xAxis, $yAxis,
$iThumbnailWidth,
$iThumbnailHeight,
$iThumbnailWidth,
$iThumbnailHeight);
imagedestroy($img);
imagedestroy($tmpimg);
$img = $tmp2img;
}
}
// Display the image using the header function to specify
// the type of output our page is giving
header("Content-type: image/jpeg");
imagejpeg($img);
}
?>
You can adjust the compression level using the third parameter to imagejpeg. For top quality (but biggest file size) use:
imagejpeg($img, NULL, 100);
A quality value of 90 will probably give you a reasonable balance between quality and file size.
Then again, the kind of image you have in the example may be best saved as PNG, with imagepng. The JPEG format is best used for photographic images.
Looks like you're destroying the image yourself:
imagedestroy($tmpimg);
$img = $tmp2img;
... snip ...
imagejpeg($tmpimg);
You cannot imagedestroy() until AFTER you have completely finished using the GD image handle, which includes outputting it via imagejpeg. once it's destroyed, the image is GONE from memory and the handle variable becomes invalid.
I'm using this jQuery plugin to crop images:
http://www.tmatthew.net/jwindowcrop
As you can see, it's really easy to use it on jQuery side, but my problem is with cropping the real image with PHP/GD.
with some goggling, I got:
$targ_w = $targ_h = 150;
$jpeg_quality = 90;
$src = 'demo_files/flowers.jpg';
$img_r = imagecreatefromjpeg($src);
$dst_r = ImageCreateTrueColor( $targ_w, $targ_h );
imagecopyresampled($dst_r,$img_r,0,0,$_POST['x'],$_POST['y'],
$targ_w,$targ_h,$_POST['w'],$_POST['h']);
header('Content-type: image/jpeg');
imagejpeg($dst_r, null, $jpeg_quality);
But it's not taking care of zoom ins/zoom outs made by the jQuery plugin, how I should crop the image and save it using this plugin and PHP?
I figured this out, here is my code in case of anyone else has the same question, the cropping will be done by Zebra image class:
http://stefangabos.ro/php-libraries/zebra-image/#documentation
PHP:
// The variables we got from the plugin in upload page:
$x = intval($_POST['x']);
$y = intval($_POST['y']);
$w = intval($_POST['w']);
$h = intval($_POST['h']);
// The img file which we want to crop
$tmp_file = 'path/to/img';
// Now include the Zebra class
include_once('path/to/Zebra_Image.php');
$image = new Zebra_Image();
$image -> preserve_aspect_ratio = true;
$image -> enlarge_smaller_images = true;
$image -> preserve_time = true;
$image -> jpeg_quality = 100;
// Now imagine that the user has selected the area which he want with the plugin, and we also want to make the image out put in a specific size(200*225):
$target_path = 'new/img/path'; // the output img path
$image -> source_path = $tmp_file;
$image -> target_path = $target_path;
$image -> crop($x, $y, $x + $w, $y + $h);
$image -> source_path = $target_path;
$image -> resize(200, 225, ZEBRA_IMAGE_CROP_CENTER);
I am also using jwindowcrop. When you click jwindowcrop's zoom, the w and h changes. (see attached picture)
You have to make sure you used the correct parameters as stated in the php manual
http://www.php.net/manual/en/function.imagecopyresampled.php
In my case, I used imagecopyresized and I could crop the image properly including the zooms
dst_image
Destination image link resource.
src_image
Source image link resource.
dst_x
x-coordinate of destination point.
(in my case the destination image should start from upper left corner)
dst_y
y-coordinate of destination point.
(in my case the destination image should start from upper left corner)
src_x
x-coordinate of source point.
(the x-coordinate returned by the cropping function e.g. crop image from x=231, 231 pixels far from the left edge)
src_y
y-coordinate of source point.
(the x-coordinate returned by the cropping function e.g. crop image from y=706, 706 pixels far from the top edge)
dst_w
Destination width.
(in my case, my new image should have a width of 800px)
dst_h
Destination height.
(in my case, my new image should have a height of 400px)
src_w
Source width.
(when my cropping function zooms, it changes the width and height of the original image)
src_h
Source height.
(when my cropping function zooms, it changes the width and height of the original image)
imagecopyresized(dst_image, src_image, 0, 0, 231, 706, 800, 400, 521, 318);