I have created a simple PHP script to crop an image that has been previously uploaded to the server by the user and save it in another folder as some kind of a thumbnail.
$src_x = $_POST['left']; // Crop start x
$src_y = $_POST['top']; // Crop start y
$dst_w = $_POST['dim']; // Thumb width
$dst_h = $_POST['dim']; // Thumb height
$src_w = $_POST['dim']; // $src_x + $dst_w
$src_h = $_POST['dim']; // $src_y + $dst_h
$contact = $_POST['contact'];
$ratio = $_POST['ratio'];
$file_tmp = $_POST['file_tmp'];
$file_ext = strtolower(end(explode('.', $file_tmp)));
$img_info = getimagesize($file_tmp);
if ($file_ext == 'png') {
$src = imagecreatefrompng($file_tmp);
}
else if ($file_ext == 'jpeg' || $file_ext == 'jpg') {
$src = imagecreatefromjpeg($file_tmp);
}
else if ($file_ext == 'gif') {
$src = imagecreatefromgif($file_tmp);
}
$dst = imagecreatetruecolor(154, 154);
imagecopyresampled($dst, $src, 0, 0, $src_x * $ratio, $src_y * $ratio, 154, 154, $src_w * $ratio, $src_h * $ratio);
$img_name = $contact.'.png';
imagepng ($dst, '../images/invitados/'.$img_name);
The script works 100% fine with all jpeg / jpg / gif / png's EXCEPT for those images that have been imported by the user with iPhoto... Does anyone know what is going on??? I am going crazy 'cause I have no idea where the problem might be... The script doesn't even return a black image, so it doesn't even get to create the png...
Please help!
Many thanks
Check the image format that has been exported from iPhoto.Photos from iPhoto can be exported as JPEG | PNG | TIFF.
Maybe the images that you are trying to crop is in a TIFF format which is not included on condition on your script.
Related
This script helps me crop and save images. every time i save an image it saves has crop.jpg .. can i save it in a different name? i have an input field with image name.. "$_POST['imgname']" how can i use this has image name for the cropped image?
<?php
$canvasImg = $_POST['img'];
$data = base64_decode($canvasImg);
$File = "captured.jpg";
$Handle = fopen($File, 'w');
fwrite($Handle, $data);
fclose($Handle);
$src_image = imagecreatefrompng($File);
$width = imagesx($src_image);
$height = imagesy($src_image);
$dst_x = 0;
$dst_y = 0;
$src_x = $width*0.350; // Crop Start X
$src_y = $height*0.165; // Crop Srart Y
$dst_w = $width*0.294; // Thumb width
$dst_h = $height*0.470; // Thumb height
$src_w = $dst_w; // $src_x + $dst_w
$src_h = $dst_h; // $src_y + $dst_h
$image = imagecreatetruecolor($dst_w, $dst_h);
imagealphablending($image, false);
$col=imagecolorallocatealpha($image,255,255,255,127);
imagefilledrectangle($image,0,0,$dst_w, $dst_h,$col);
imagealphablending($image,true);
imagecopyresampled($image, $src_image, $dst_x, $dst_y, $src_x, $src_y, $dst_w, $dst_h, $src_w, $src_h);
imagealphablending($image,true);
imagealphablending($image,false);
imagesavealpha($image,true);
imagepng($image, "images/crop.jpeg");
imagedestroy($image);
?>
If I understand your question correctly, you just need to make a new filename for the imagepng() to use.
This would seem a simple solution:
$canvasImg = $_POST['img'];
$data = base64_decode($canvasImg);
$File = "captured.jpg";
...
// create a new filesname for the cropped image in $save_to
$save_to = 'images/';
$save_to .= str_replace(array('.jpg','.png'), '', $data ) // remove original extension if it existed
$save_to .= '_crop.jpg';
// use this new name to save the cropped image
imagepng($image, $save_to);
However your code does not seem to make much sence. You accept an image name in $_POST['img'] then save it to a file called capured.jpg and then open it as a .png in $src_image = imagecreatefrompng($File);
I assume you must only be accepting .png files, and in that case why save it as a .jpg.
See what I mean, there appears to be a whole lot of confusion in your code.
QUESTION EDITED
Below is a simple script to allow users upload pictures. Once the upload is done, the pictures are displayed as a 170px(h) x 150px(w) thumbnail.
Most of the pictures look distorted once resized, so I guess I need to scale them too.
I'm stuck at saving the new image dimensions. See TODO.
<?php
if ($_SERVER["REQUEST_METHOD"] == "POST")
{
$maxWidth = 150;
$maxHeight = 170;
$name = $_FILES ['image'] ['name'];
$type = $_FILES ["image"] ["type"];
$size = $_FILES ["image"] ["size"];
$tmp_name = $_FILES ['image'] ['tmp_name'];
list($originalWidth, $originalHeight) = getimagesize($tmp_name);
if ($originalWidth > $maxWidth || $originalHeight > $maxHeight)
{
if ($originalWidth / $maxWidth > $originalHeight / $maxHeight)
{
// width is the limiting factor
$width = $maxWidth;
$height = floor($width * $originalHeight / $originalWidth);
} else {
// height is the limiting factor
$height = $maxHeight;
$width = floor($height * $originalWidth / $originalHeight);
}
// Resample
$image_p = imagecreatetruecolor($maxwidth, $maxheight);
$image = imagecreatefromjpeg($filename);
imagecopyresampled($image_p, $image, 0, 0, 0, 0, $maxwidth, $maxheight,
$originalWidth, $originalHeight);
TODO: how do I save the new dimensions to $location ?
//start upload process
$RandomNumber = uniqid();
$location = "uploads/$RandomNumber";
move_uploaded_file($tmp_name, $location);
query("UPDATE users SET profilepic = '".$location."' WHERE id = '$id'");
}
?>
Some of my code is inspired from this question:
Distorted image resize with PHP
As for you question: "How can I get the initial dimensions of the picture the user wants to upload?"
From the manual:
list($width, $height, $type, $attr) = getimagesize("img/flag.jpg");
With that in mind, you may be able to replace the file path in the above example with $_FILES["image"] to get the dimensions data.
Once you have the original dimensions, you can adjust the image to be smaller while preserving the original aspect ratio.
For error checking, you would probably want to either check that there is only one file in $_FILES["image"], or loop through an array in the event you allow for multiple image uploads using the same name for each image's HTML input tag.
I have a custom class that helps me do this in projects. Feel free to use my code:
https://gist.github.com/695Multimedia/7117003
I am modifieng this plug in to save a record of the path and make a thumbnail image and save that aswell http://bakery.cakephp.org/articles/srs2012/2012/03/12/ajaxmultiupload_plugin_for_cake_2_0_x_and_2_1
I modified the upload.php in the plugin like this:
function save($path, $folder, $filename) {
$input = fopen("php://input", "r");
$temp = tmpfile();
$realSize = stream_copy_to_stream($input, $temp);
fclose($input);
if ($realSize != $this->getSize()){
return false;
}
$width = 290;
$height = 146;
$target = fopen($path, "w");
//$this->Upload->setImage($this->Image);
fseek($temp, 0, SEEK_SET);
stream_copy_to_stream($temp, $target);
fclose($target);
$val = $this->resizeImage($filename, $filename, $folder, $folder.'/small/', $width, $height, 100);
$this->saveToDatabase(array('path' => $folder.$filename, 'thumb' => $folder.'/small/'.$filename));
return true;
}
This is the function i made to save:
function saveToDatabase($data){
$this->Image->save($data);
}
The following I added to create the thumbnail:
function resizeImage($src_img, $dst_img, $src_path2, $dst_path2, $dst_w, $dst_h, $dst_quality){
//Stop and giving an error if the file does not exists.
$src_path = 'img/';
$dst_path = 'img/';
$src_path .= $src_path2;
$dst_path .= $dst_path2;
if(file_exists($src_path . basename($src_img)) == false){
echo 0;
}
//Get variables for the function.
//complete path of the source image.
$src_cpl = $src_path . basename($src_img);
//return $src_cpl;
//complete path of the destination image.
$dst_cpl = $dst_path . basename($dst_img);
//extension excl "." of the source image, in lowercase.
$src_ext = strtolower(end(explode(".", $src_img)));
//width and height sizes of the source image.
list($src_w, $src_h) = getimagesize($src_cpl);
//get type of image.
//return 'IETS: '.$src_cpl.' :IETS';
$src_type = exif_imagetype($src_cpl);//
//Checking extension and imagetype of the source image and path.
if( ($src_ext =="jpg") && ($src_type =="2") ){
$src_img = imagecreatefromjpeg($src_cpl);
}else if( ($src_ext =="jpeg") && ($src_type =="2") ){
$src_img = imagecreatefromjpeg($src_cpl);
}else if( ($src_ext =="gif") && ($src_type =="1") ){
$src_img = imagecreatefromgif($src_cpl);
}else if( ($src_ext =="png") && ($src_type =="3") ){
$src_img = imagecreatefrompng($src_cpl);
}else{
die('<p>The file "'. $src_img . '" with the extension "' . $src_ext . '" and the imagetype "' . $src_type . '" is not a valid image. Please upload an image with the extension JPG, JPEG, PNG or GIF and has a valid image filetype.</p>');
}
//Get heights and width so the image keeps its ratio.
$x_ratio = $dst_w / $src_w;
$y_ratio = $dst_h / $src_h;
if( (($x_ratio > 1) || ($y_ratio > 1)) && ($x_ratio > $y_ratio) ){
//If one of the sizes of the image is smaller than the destination (normal: more height than width).
$dst_w = ceil($y_ratio * $src_w);
$dst_h = $dst_h;
}elseif( (($x_ratio > 1) || ($y_ratio > 1)) && ($y_ratio > $x_ratio) ){
//If one of the sizes of the image is smaller than the destination (landscape: more width than height).
$dst_w = $dst_w;
$dst_h = ceil($x_ratio * $src_h);
}elseif (($x_ratio * $src_h) < $dst_h){
//if the image is landscape (more width than height).
$dst_h = ceil($x_ratio * $src_h);
$dst_w = $dst_w;
}elseif (($x_ratio * $src_h) > $dst_h){
//if the image is normal (more height than width).
$dst_h = ceil($x_ratio * $src_h);
$dst_w = $dst_w;
}else{
//if the image is normal (more height than width).
$dst_w = ceil($y_ratio * $src_w);
$dst_h = $dst_h;
}
// Creating the resized image.
$dst_img=imagecreatetruecolor($dst_w,$dst_h);
$result = imagecopyresampled($dst_img,$src_img,0,0,0,0,$dst_w, $dst_h,$src_w,$src_h);
// Saving the resized image.
$result2 = imagejpeg($dst_img,$dst_cpl,$dst_quality);
return 'dfdfhdfhhgfddghhgffddghdghhdgghgfhdh: '.$result.'|||asdasda'.$result2;
// Cleaning the memory.
imagedestroy($src_img);
imagedestroy($dst_img);
}
enter code here
Now I already used this code on the same server and it worked perfectly fine. But in my return value i get the following:
[uploader] responseText = dfdfhdfhhgfddghhgffddghdghhdgghgfhdh: 1|||asdasda{"success":true}
The function imagejpeg does not return anything.
Now what could be wrong? I am only an intern and I can't figure out what is wrong.
Greetings,
Harm.
bump?
See http://php.net/manual/en/function.imagejpeg.php - I think, that you have problem in function imagejpeg - see parameter filename.
If there will be more problems, see http://www.php.net/manual/en/function.gd-info.php
I'm using this script to create a watermark on one of client's websites the problem is that one watermark is suitable for one image and unsuitable for another.
Portrait
Landscape
Here is the script:
<?php
// this script creates a watermarked image from an image file - can be a .jpg .gif or .png file
// where watermark.gif is a mostly transparent gif image with the watermark - goes in the same directory asthis script
// where this script is named watermark.php
// call this script with an image tag
// <img src="watermark.php?path=imagepath"> where path is a relative path such as subdirectory/image.jpg
$imagesource = $_GET['path'];
$filetype = substr($imagesource,strlen($imagesource)-4,4);
$filetype = strtolower($filetype);
if($filetype == ".gif") $image = #imagecreatefromgif($imagesource);
if($filetype == ".jpg") $image = #imagecreatefromjpeg($imagesource);
if($filetype == ".png") $image = #imagecreatefrompng($imagesource);
if (!$image) die();
//This bit is the dynamic bit
if(imagesx($image) <=1100){
$watermark = #imagecreatefromgif('watermark_port.gif');
}elseif(imagesx($image) <=1600 && $imagewidth >1100){
$watermark = #imagecreatefromgif('watermark_lans.gif');
}elseif(imagesx($image) >1600){
$watermark = #imagecreatefromgif('watermark_lans.gif');
};
//End of dynamic code
$imagewidth = imagesx($image);
$imageheight = imagesy($image);
$watermarkwidth = imagesx($watermark);
$watermarkheight = imagesy($watermark);
$startwidth = (($imagewidth - $watermarkwidth)/2);
$startheight = (($imageheight - $watermarkheight)/2);
imagecopy($image, $watermark, $startwidth, $startheight, 0, 0, $watermarkwidth,
$watermarkheight);
imagejpeg($image);
imagedestroy($image);
imagedestroy($watermark);
?>
However the dynamic watermark doesn't work. What i want is if the image is under 1100px wide then it uses the portrait version and if it is over that to use the landscape version instead.
Any idea would be greatly apprieciated.
Thanks,
David
What your "dynamic part" is doing is basically summed up as:
if something
do A
else if something
do B
else
do B
The middle one is completely redundant.
What you need is just:
$watermark =
imagecreatefromgif("watermark_".(imagesx($image) <= 1100 ? "port" : "lans").".gif");
I'd like crop an image in PHP and save the file. I know your supposed to use the GD library but i'm not sure how. Any ideas?
Thanks
You could use imagecopy to crop a required part of an image. The command goes like this:
imagecopy (
resource $dst_im - the image object ,
resource $src_im - destination image ,
int $dst_x - x coordinate in the destination image (use 0) ,
int $dst_y - y coordinate in the destination image (use 0) ,
int $src_x - x coordinate in the source image you want to crop ,
int $src_y - y coordinate in the source image you want to crop ,
int $src_w - crop width ,
int $src_h - crop height
)
Code from PHP.net - a 80x40 px image is cropped from a source image
<?php
// Create image instances
$src = imagecreatefromgif('php.gif');
$dest = imagecreatetruecolor(80, 40);
// Copy
imagecopy($dest, $src, 0, 0, 20, 13, 80, 40);
// Output and free from memory
header('Content-Type: image/gif');
imagegif($dest);
imagedestroy($dest);
imagedestroy($src);
?>
This function will crop image maintaining image aspect ratio :)
function resize_image_crop($image, $width, $height)
{
$w = #imagesx($image); //current width
$h = #imagesy($image); //current height
if ((!$w) || (!$h)) { $GLOBALS['errors'][] = 'Image couldn\'t be resized because it wasn\'t a valid image.'; return false; }
if (($w == $width) && ($h == $height)) { return $image; } //no resizing needed
$ratio = $width / $w; //try max width first...
$new_w = $width;
$new_h = $h * $ratio;
if ($new_h < $height) { //if that created an image smaller than what we wanted, try the other way
$ratio = $height / $h;
$new_h = $height;
$new_w = $w * $ratio;
}
$image2 = imagecreatetruecolor ($new_w, $new_h);
imagecopyresampled($image2,$image, 0, 0, 0, 0, $new_w, $new_h, $w, $h);
if (($new_h != $height) || ($new_w != $width)) { //check to see if cropping needs to happen
$image3 = imagecreatetruecolor ($width, $height);
if ($new_h > $height) { //crop vertically
$extra = $new_h - $height;
$x = 0; //source x
$y = round($extra / 2); //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
} else {
$extra = $new_w - $width;
$x = round($extra / 2); //source x
$y = 0; //source y
imagecopyresampled($image3,$image2, 0, 0, $x, $y, $width, $height, $width, $height);
}
imagedestroy($image2);
return $image3;
} else {
return $image2;
}
}
To crop an image using GD you need to use a combination of GD methods, and if you look at "Example #1" on PHP's documentation of the imagecopyresampled method, it shows you how to crop and output an image, you would just need to add some code to that to capture and write the output to a file...
http://us2.php.net/manual/en/function.imagecopyresampled.php
There are also other options, including Image Magick which, if installed on your server, can be accessed directly using PHP's exec method (or similar) or you can install the PHP Imagick extension, which yields higher quality images and, in my opinion, is a little more intuitive and flexible to work with.
Finally, I've used the open source PHPThumb class library, which has a pretty simple interface and can work with multiple options depending on what's on your server, including ImageMagick and GD.
I use this script in some projects and it's pretty easy to use:
http://shiftingpixel.com/2008/03/03/smart-image-resizer/
The script requires PHP 5.1.0 (which is out since 2005-11-24 - time to upgrade if not yet at this version) and GD (which is rarely missing from good Web hosts).
Here is an example of it's use in your HTML:
<img src="/image.php/coffee-bean.jpg?width=200&height=200&image=/wp-content/uploads/2008/03/coffee-bean.jpg" alt="Coffee Bean" />
I just created this function and it works for my needs, creating a centered and cropped thumbnail image. It is streamlined and doesn't require multiple imagecopy calls like shown in webGautam's answer.
Provide the image path, the final width and height, and optionally the quality of the image. I made this for creating thumbnails, so all images are saved as JPGs, you can edit it to accommodate other image types if you require them. The main point here is the math and method of using imagecopyresampled to produce a thumbnail. Images are saved using the same name, plus the image size.
function resize_crop_image($image_path, $end_width, $end_height, $quality = '') {
if ($end_width < 1) $end_width = 100;
if ($end_height < 1) $end_height = 100;
if ($quality < 1 || $quality > 100) $quality = 60;
$image = false;
$dot = strrpos($image_path,'.');
$file = substr($image_path,0,$dot).'-'.$end_width.'x'.$end_height.'.jpg';
$ext = substr($image_path,$dot+1);
if ($ext == 'jpg' || $ext == 'jpeg') $image = #imagecreatefromjpeg($image_path);
elseif($ext == 'gif') $image = #imagecreatefromgif($image_path);
elseif($ext == 'png') $image = #imagecreatefrompng($image_path);
if ($image) {
$width = imagesx($image);
$height = imagesy($image);
$scale = max($end_width/$width, $end_height/$height);
$new_width = floor($scale*$width);
$new_height = floor($scale*$height);
$x = ($new_width != $end_width ? ($width - $end_width) / 2 : 0);
$y = ($new_height != $end_height ? ($height - $end_height) / 2 : 0);
$new_image = #imagecreatetruecolor($new_width, $new_height);
imagecopyresampled($new_image,$image,0,0,$x,$y,$new_width,$new_height,$width - $x,$height - $y);
imagedestroy($image);
imagejpeg($new_image,$file,$quality);
imagedestroy($new_image);
return $file;
}
return false;
}
You can use below method to crop image,
/*parameters are
$image =source image name
$width = target width
$height = height of image
$scale = scale of image*/
function resizeImage($image,$width,$height,$scale) {
//generate new image height and width of source image
$newImageWidth = ceil($width * $scale);
$newImageHeight = ceil($height * $scale);
//Create a new true color image
$newImage = imagecreatetruecolor($newImageWidth,$newImageHeight);
//Create a new image from file
$source = imagecreatefromjpeg($image);
//Copy and resize part of an image with resampling
imagecopyresampled($newImage,$source,0,0,0,0,$newImageWidth,$newImageHeight,$width,$height);
//Output image to file
imagejpeg($newImage,$image,90);
//set rights on image file
chmod($image, 0777);
//return crop image
return $image;
}