Crop Image using imagecopyresampled + Jcrop - php

I'm using Jcrop to crop images from the user. I followed the tutorial here: http://deepliquid.com/content/Jcrop_Implementation_Theory.html. Here's my code
private function resizeImage($file_info)
{
$dst_w = $dst_h = 150;
$jpeg_quality = 90;
$src = realpath($file_info['directory'] . '/' . $file_info['name']);
// CHMOD before cropping
chmod($src, 0777);
switch (strtolower($file_info['mime'])) {
case 'image/jpeg':
$src_img = imagecreatefromjpeg($src);
break;
case 'image/png':
$src_img = imagecreatefrompng($src);
break;
case 'image/gif':
$src_img = imagecreatefromgif($src);
break;
default:
exit('Unsupported type: ' . $file_info['mime']);
}
$dst_img = imagecreatetruecolor($dst_w, $dst_h);
// Resize and crop the image
imagecopyresampled(
$dst_img, $src_img, // Destination and Source image link resource
0, 0, // Coordinate of destination point
$this->crop['x'], $this->crop['y'], // Coordinate of source point
$dst_w, $dst_h, // Destination width and height
$this->crop['w'], $this->crop['h'] // Source width and height
);
// Output the image
switch (strtolower($file_info['mime'])) {
case 'image/jpeg':
imagejpeg($dst_img, null, $jpeg_quality);
break;
case 'image/png':
imagepng($dst_img);
break;
case 'image/gif':
imagegif($dst_img);
break;
default:
exit('Unsupported type: ' . $file_info['mime']);
}
}
I have checked both directory and file are writable (0777 permission). All variables I'm using are well-defined as well, nothing error. However, the final image is still in its original form, not cropped.
Anybody knows why it's not working? Any help is appreciated.

you're using list() to get the width and height of the source image, but you're not using it in your imagecopyresampled() call. Everything else looks fine as far as i can see, if that doesn't fix it the problem is probably somewhere else in the class.
here's my cropping method for reference, if it helps.
/**
* Crops the image to the given dimensions, at the given starting point
* defaults to the top left
* #param type $width
* #param type $height
* #param type $x
* #param type $y
*/
public function crop($new_width, $new_height, $x = 0, $y = 0){
$img = imagecrop($this->image, array(
"x" => $x,
"y" => $y,
"width" => $new_width,
"height" => $new_height
));
$this->height = $new_height;
$this->width = $new_width;
if(false !== $img) $this->image = $img;
else self::Error("Could not crop image.");
return $this;
}
resizing method, for reference..
/**
* resizes the image to the dimensions provided
* #param type $width (of canvas)
* #param type $height (of canvas)
*/
public function resize($width, $height){
// Resize the image
$thumb = imagecreatetruecolor($width, $height);
imagealphablending($thumb, false);
imagesavealpha($thumb, true);
imagecopyresampled($thumb, $this->image, 0, 0, 0, 0, $width, $height, $this->width, $this->height);
$this->image = $thumb;
$this->width = $width;
$this->height = $height;
return $this;
}

Related

Problem when uploading and saving image in database

Hello guys and ladies,
I am trying to upload and save images in a database. My code is working, but when I test it then after three or four times the image will save partially like this:
In my code I can save up to 12 images (if uploaded). And i'm testing with 4 images.
What am I doing wrong? Is it a memory problem? And if it is..what is causing it?
thank you for helping.
My code is:
//save up to 12 images in database
for($i=1;$i<=12;$i++){
$fileName = $_FILES['image'.$i]['name'];
if ($fileName){
try{
list($origWidth, $origHeight, $type) = getimagesize($_FILES['image'.$i]['tmp_name']);
$temp_name = "tempupload/".$fileName;
//make thumbnail to save in database
//resize the image to 200px and save as/in $temp_name (see resizeImage function)
resizeImage($_FILES['foto'.$i]['tmp_name'], $temp_name, 200, 200);
//retrieve saved image to put a watermark on it
switch(strtolower(image_type_to_mime_type($type)))
{
case 'image/jpeg':
$im2 = #imagecreatefromjpeg($temp_name);
break;
case 'image/png':
$im2 = #imagecreatefrompng($temp_name);
break;
}
//put watermark
$watermark = imagecreatefrompng('../assets/images/logo/watermark.png');
$marge_right = 10;
$marge_bottom = 10;
$sx = imagesx($watermark);
$sy = imagesy($watermark);
imagecopy($im2, $watermark, imagesx($im2) - $sx - $marge_right, imagesy($im2) - $sy - $marge_bottom, 0, 0, imagesx($watermark), imagesy($watermark));
//save image with watermark
switch(strtolower(image_type_to_mime_type($type)))
{
case 'image/jpeg':
imagejpeg($im2, $temp_name);
break;
case 'image/png':
imagepng($im2, $temp_name);
break;
}
//open saved temp image
$saved_temp = fopen($temp_name,"rb");
//addslashes to image to save in database as BLOB
$image = addslashes(fread($saved_temp ,filesize($temp_name)));
fclose($saved_temp );
//End thumbnail
//Next part is to save the image in database in 1200px if user want this.
//this is used so that the user can download and use the image afterwards
$downloadimage="";
if(($_POST['image'.$i.'_Save']!="no") && ($_SESSION['package']!="A")){
//if width or height are smaller 700 us original width or height
$w = ($origWidth > 1200)?1200:$origWidth;
$h = ($origHeight > 1200)?1200:$origHeight;
if(($origWidth > 1200) || ($origHeight > 1200)){
//use same $temp_name to save memory????
resizeImage($_FILES['image'.$i]['tmp_name'], $temp_name, $w, $h,100);
}else{
//if image is to small, then move and save as $temp_name
move_uploaded_file($_FILES['image'.$i]["tmp_name"],$temp_name);
}
//put watermark
if(($_SESSION['package']=="B")){
// Get dimensions and type of $temp_name.
list($origWidth, $origHeight, $type) = getimagesize($temp_name);
switch(strtolower(image_type_to_mime_type($type)))
{
case 'image/jpeg':
$im2 = #imagecreatefromjpeg($temp_name);
break;
case 'image/png':
$im2 = #imagecreatefrompng($temp_name);
break;
}
imagecopy($im2, $watermark, imagesx($im2) - $sx - $marge_right, imagesy($im2) - $sy - $marge_bottom, 0, 0, imagesx($watermark), imagesy($watermark));
switch(strtolower(image_type_to_mime_type($type)))
{
case 'image/jpeg':
imagejpeg($im2, $temp_name);
break;
case 'image/png':
imagepng($im2, $temp_name);
break;
}
}
$saved_temp = fopen($temp_name,"rb");
$downloadimage = addslashes(fread($saved_temp ,filesize($temp_name)));
fclose($saved_temp );
}
//End making downloadimage
//SQL to save images in database
if(empty($downloadimage)){
$sql = "INSERT INTO tb_images(image,strange_id) VALUES (:image,:strange_id)";
$st = $conn->prepare($sql);
}else{
$sql = "INSERT INTO tb_images(image,strange_id,downloadimage,type) VALUES (:image,:strange_id,:downloadimage,:type)";
$st = $conn->prepare($sql);
$st->bindValue( ":downloadimage", $downloadimage, PDO::PARAM_LOB );
$st->bindValue( ":type", strtolower(image_type_to_mime_type($type)), PDO::PARAM_STR );
}
$st->bindValue( ":image", $image, PDO::PARAM_LOB );
$st->bindValue( ":strange_id", $strange_id, PDO::PARAM_INT );
$st->execute();
imagedestroy($watermark);
unlink($temp_name);
imagedestroy($im2);
}
catch (\Exception $e){
echo e;
}
}
}
the resize function
/**
* Resize image - preserve ratio of width and height.
* #param string $sourceImage path to source JPEG/PNG image
* #param string $targetImage path to final JPEG/PNG image file
* #param int $maxWidth maximum width of final image (value 0 - width is optional)
* #param int $maxHeight maximum height of final image (value 0 - height is optional)
* #param int $quality quality of final image (0-100)
* #return bool
*/
function resizeImage($sourceImage, $targetImage, $maxWidth, $maxHeight, $quality = 80)
{
$isValid = #getimagesize($sourceImage);
if (!$isValid)
{
return false;
}
// Get dimensions and type of source image.
list($origWidth, $origHeight, $type) = getimagesize($sourceImage);
if ($maxWidth == 0)
{
$maxWidth = $origWidth;
}
if ($maxHeight == 0)
{
$maxHeight = $origHeight;
}
// Calculate ratio of desired maximum sizes and original sizes.
$widthRatio = $maxWidth / $origWidth;
$heightRatio = $maxHeight / $origHeight;
// Ratio used for calculating new image dimensions.
$ratio = min($widthRatio, $heightRatio);
// Calculate new image dimensions.
$newWidth = (int)$origWidth * $ratio;
$newHeight = (int)$origHeight * $ratio;
// Create final image with new dimensions.
$newImage = imagecreatetruecolor($newWidth, $newHeight);
// Obtain image from given source file.
switch(strtolower(image_type_to_mime_type($type)))
{
case 'image/jpeg':
$image = #imagecreatefromjpeg($sourceImage);
if (!$image)
{
return false;
}
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight);
if(imagejpeg($newImage,$targetImage,$quality))
{
// Free up the memory.
imagedestroy($image);
imagedestroy($newImage);
return true;
}
break;
case 'image/png':
$image = #imagecreatefrompng($sourceImage);
if (!$image)
{
return false;
}
imagecopyresampled($newImage, $image, 0, 0, 0, 0, $newWidth, $newHeight, $origWidth, $origHeight);
if(imagepng($newImage,$targetImage, floor($quality / 10)))
{
// Free up the memory.
imagedestroy($image);
imagedestroy($newImage);
return true;
}
break;
default:
return false;
}
}
Oke... after much testing... this is the solution of my own problem :)
first of all this line...
resizeImage($_FILES['image'.$i]['tmp_name'], $temp_name, $w, $h,100);
Setting up quality 100% for PNG was a problem. I don't know why, but what I did is just replace this:
imagepng($newImage,$targetImage, floor($quality / 10))
with:
imagepng($newImage,$targetImage)
And I did it also for the JPEG.
Then the second problem was in my database. BLOB had to be LONG BLOB.
But now I am not storing the images in the database anymore. I am saving them in a folder. Not because of the LONG BLOB issue, but just because it is faster and less work to do.

Dart/Flutter Alternative to PHP's resize_crop_image?

Currently, I am resizing avatars on my server using PHP's resize_crop_image. The code below takes an image, crops and resizes it so that it's exactly 500px X 500px square.
resize_crop_image(500, 500, $filename, $filename);
But I'd like to move this process from the server to the flutter app. Most of the plugins I'm seeing on pub.dev are overkill with the user cropping the image using a crop tool. But I'd like this function to happen automatically the way I currently do it in PHP.
Here's the resize_crop_image code;
function resize_crop_image($max_width, $max_height, $source_file, $dst_dir, $quality = 100){
$imgsize = getimagesize($source_file);
$width = $imgsize[0];
$height = $imgsize[1];
$mime = $imgsize['mime'];
switch($mime){
case 'image/gif':
$image_create = "imagecreatefromgif";
$image = "imagegif";
break;
case 'image/png':
$image_create = "imagecreatefrompng";
$image = "imagepng";
$quality = 10;
break;
case 'image/jpeg':
$image_create = "imagecreatefromjpeg";
$image = "imagejpeg";
$quality = 100;
break;
default:
return false;
break;
}
$dst_img = imagecreatetruecolor($max_width, $max_height);
$src_img = $image_create($source_file);
$width_new = $height * $max_width / $max_height;
$height_new = $width * $max_height / $max_width;
//if the new width is greater than the actual width of the image, then the height is too large and the rest cut off, or vice versa
if($width_new > $width){
//cut point by height
$h_point = (($height - $height_new) / 2);
//copy image
imagecopyresampled($dst_img, $src_img, 0, 0, 0, $h_point, $max_width, $max_height, $width, $height_new);
}else{
//cut point by width
$w_point = (($width - $width_new) / 2);
imagecopyresampled($dst_img, $src_img, 0, 0, $w_point, 0, $max_width, $max_height, $width_new, $height);
}
$image($dst_img, $dst_dir, $quality);
if($dst_img)imagedestroy($dst_img);
if($src_img)imagedestroy($src_img);
}
?>
You could use this library: flutter_native_image for resizing/croping your images.
Important to take a look at the other parameters of this function, you can probably customize the way the image will be cropped.
Something like that:
ImageProperties properties = await FlutterNativeImage.getImageProperties(file.path);
File croppedFile = await FlutterNativeImage.cropImage(file.path, originX, originY, 500, 500);
originX/originY: x/y position for the cut.

Laravel 5.6: Create image thumbnails

In my old PHP apps i used to run a function like the one bellow to create jpeg image thumbnails.
function imageThumbanail() {
$image_src = imagecreatefromjpeg('http://examplesite.com/images/sample-image.jpg');
$thumbnail_width = 180; //Desirable thumbnail width size 180px
$image_width = imagesx($image_src); //Original image width size -> 1080px
$image_height = imagesy($image_src); //Original image height size -> 1080px
$thumbnail_height = floor( $image_height * ( $thumb_width / $image_width ) ); //Calculate the right thumbnail height depends on given thumbnail width
$virtual_image = imagecreatetruecolor($thumbnail_width, $thumbnail_height);
imagecopyresampled($virtual_image, $image_src, 0, 0, 0, 0, $thumbnail_width, $thumbnail_height, $image_width, $image_height);
header('Content-Type: image/jpeg');
imagejpeg($virtual_image, null, 100);
imagedestroy($virtual_image); //Free up memory
}
The problem is that now i'd like to run a similar function in a laravel 5.6 app, so i created a controller with the exact same function but instead of get as an output the image thumbnail i get question marks and strange diamond icons, something like encoded version of php gd library jpeg image.
I tried to use return response()->file($pathToFile); as laravel documentation describes but i won't store in a location the thumbnail image.
Any ideas?
Thank you in advance!
I recommend you this package is very simple to install and use it and very kind with programming.
Its called Intervention
Intervention package to handle images
You can make a thumbnail very simple like the following :
$img = Image::make('public/foo.jpg')->resize(320, 240)->insert('public/watermark.png');
Resize and crop image by center
No need to install and include any package. Just create a helper in laravel / lumen and put below code in that helper file and use it wherever you want:
function resize_crop_image($max_width, $max_height, $source_file, $dst_dir, $quality = 80){
$imgsize = getimagesize($source_file);
$width = $imgsize[0];
$height = $imgsize[1];
$mime = $imgsize['mime'];
switch($mime){
case 'image/gif':
$image_create = "imagecreatefromgif";
$image = "imagegif";
break;
case 'image/png':
$image_create = "imagecreatefrompng";
$image = "imagepng";
$quality = 7;
break;
case 'image/jpeg':
$image_create = "imagecreatefromjpeg";
$image = "imagejpeg";
$quality = 80;
break;
default:
return false;
break;
}
$dst_img = imagecreatetruecolor($max_width, $max_height);
$src_img = $image_create($source_file);
$width_new = $height * $max_width / $max_height;
$height_new = $width * $max_height / $max_width;
//if the new width is greater than the actual width of the image, then the height is too large and the rest cut off, or vice versa
if($width_new > $width){
//cut point by height
$h_point = (($height - $height_new) / 2);
//copy image
imagecopyresampled($dst_img, $src_img, 0, 0, 0, $h_point, $max_width, $max_height, $width, $height_new);
}else{
//cut point by width
$w_point = (($width - $width_new) / 2);
imagecopyresampled($dst_img, $src_img, 0, 0, $w_point, 0, $max_width, $max_height, $width_new, $height);
}
$image($dst_img, $dst_dir, $quality);
if($dst_img)imagedestroy($dst_img);
if($src_img)imagedestroy($src_img);
}
//usage example
resize_crop_image(100, 100, "test.jpg", "test.jpg");
Code is already tested many times and working well. All the best, save your time and enjoy your life :)

Crop resize images on the fly using PHP

I'm building a wallpaper website and therefore i need to be able to resize the original image before downloading. I tried this code to resize the image:
//resize and crop image by center
function resize_crop_image($max_width, $max_height, $source_file, $dst_dir, $quality = 80){
$imgsize = getimagesize($source_file);
$width = $imgsize[0];
$height = $imgsize[1];
$mime = $imgsize['mime'];
switch($mime){
case 'image/gif':
$image_create = "imagecreatefromgif";
$image = "imagegif";
break;
case 'image/png':
$image_create = "imagecreatefrompng";
$image = "imagepng";
$quality = 7;
break;
case 'image/jpeg':
$image_create = "imagecreatefromjpeg";
$image = "imagejpeg";
$quality = 80;
break;
default:
return false;
break;
}
$dst_img = imagecreatetruecolor($max_width, $max_height);
$src_img = $image_create($source_file);
$width_new = $height * $max_width / $max_height;
$height_new = $width * $max_height / $max_width;
//if the new width is greater than the actual width of the image, then the height is too large and the rest cut off, or vice versa
if($width_new > $width){
//cut point by height
$h_point = (($height - $height_new) / 2);
//copy image
imagecopyresampled($dst_img, $src_img, 0, 0, 0, $h_point, $max_width, $max_height, $width, $height_new);
}else{
//cut point by width
$w_point = (($width - $width_new) / 2);
imagecopyresampled($dst_img, $src_img, 0, 0, $w_point, 0, $max_width, $max_height, $width_new, $height);
}
$image($dst_img, $dst_dir, $quality);
if($dst_img)imagedestroy($dst_img);
if($src_img)imagedestroy($src_img);
}
And this will do the resize:
resize_crop_image($width, $height, $image_URL, $save_URL)
This code works fine for me but i want to ONLY send the output to user's browser, since saving thousands of extra images isn't possible. There are libraries i can use, but i don't want to use a third party snippet. Is there a way to alter this code in the way i desire?
Thanks.
For your $image function , do not specify a destination directory (null) and an image stream will be created.
header("Content-type:{$mime}");
That should send the image to the user
You just need to set the proper headers and echo the output. Every PHP request "downloads a file" to the browser, more or less. You just need to specify how the browser handles it. So try something like:
header("Content-Type: $mime");
header("Content-Disposition: attachment; filename=$dst_img");
echo $dst_img;
That should do it for you.

PHP's imagepng() method saves an invalid image

I am using the GD library to automatically generate a thumbnail version of an uploaded image. I call the appropriate image____() function to save in the same format as the original. My code works fine for JPEG and GIF, but if I upload a PNG file, the resulting thumbnail is invalid. It actually only contains 33 bytes (with any source PNG that I've tried so far). This image does not display in the browser, nor can it be opened by Preview (on MacOS).
I use imagecreatetruecolor() along with imagecopyresampled() to generate the thumbnail, like this:
function _resizeImageToFit($resource, $size)
{
$sourceWidth = imagesx($resource);
$sourceHeight = imagesy($resource);
if($sourceWidth >= $sourceHeight) {
// landscape or square
$newHeight = 1.0*$size/$sourceWidth*$sourceHeight;
$newWidth = $size;
}
else {
// portrait
$newWidth = 1.0*$size/$sourceHeight*$sourceWidth;
$newHeight = $size;
}
$thmb = imagecreatetruecolor($newWidth, $newHeight);
imagecopyresampled($thmb, $resource, 0, 0, 0, 0, $newWidth, $newHeight, $sourceWidth, $sourceHeight);
return $thmb;
}
Below is the version info of my setup (It's MAMP Version 1.9.4)
PHP Version 5.3.2
GD Version bundled (2.0.34 compatible)
Here is an example of an invalid generated thumbnail image (PNG):
âPNG
IHDRdaØMì∞
I found my error. imagepng() takes a quality value range of 0 to 9, while imagejpeg() takes a range of 0 to 100 and imagegif() doesn't take any such parameter. I was trying to save a PNG with a quality of 100.
So, this is a lovely case of RTM. Thanks for your responses.
http://ca3.php.net/manual/en/function.imagepng.php
http://ca3.php.net/manual/en/function.imagejpeg.php
http://ca3.php.net/manual/en/function.imagegif.php
Try this function.
/**
* Crop new images using the source image
*
* #param string $source - Image source
* #param string $destination - Image destination
* #param integer $thumbW - Width for the new image
* #param integer $thumbH - Height for the new image
* #param string $imageType - Type of the image
*
* #return bool
*/
function cropImage($source, $destination, $thumbW, $thumbH, $imageType)
{
list($width, $height, $type, $attr) = getimagesize($source);
$x = 0;
$y = 0;
if ($width*$thumbH>$height*$thumbW) {
$x = ceil(($width - $height*$thumbW/$thumbH)/2);
$width = $height*$thumbW/$thumbH;
} else {
$y = ceil(($height - $width*$thumbH/$thumbW)/2);
$height = $width*$thumbH/$thumbW;
}
$newImage = imagecreatetruecolor($thumbW, $thumbH) or die ('Can not use GD');
/*
if ($extension=='jpg' || $extension=='jpeg') {
$image = imagecreatefromjpeg($source);
} else if ($extension=='gif') {
$image = imagecreatefromgif($source);
} else if ($extension=='png') {
$image = imagecreatefrompng($source);
}
*/
switch($imageType) {
case "image/gif":
$image = imagecreatefromgif($source);
break;
case "image/pjpeg":
case "image/jpeg":
case "image/jpg":
$image = imagecreatefromjpeg($source);
break;
case "image/png":
case "image/x-png":
$image = imagecreatefrompng($source);
break;
}
if (!#imagecopyresampled($newImage, $image, 0, 0, $x, $y, $thumbW, $thumbH, $width, $height)) {
return false;
} else {
imagejpeg($newImage, $destination,100);
imagedestroy($image);
return true;
}
}

Categories