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 :)
Related
I have tried a lot of solutions that I have found on internet but nothing is working for me. I am trying to resize and rotate the image depends on exif data but the image is not rotating. Resizing the image is working fine. But the rotation is not working. Below is the function I used to do that.
function resize_imageb($newbfile,$max_resolution){
if(file_exists($newbfile)){
$original_image = imagecreatefromjpeg($newbfile);
$exif = exif_read_data($newbfile, 0, true);
if(!empty($exif['Orientation'])) {
switch($exif['Orientation']) {
case 8:
$original_image = imagerotate($original_image,90,0);
break;
case 3:
$original_image = imagerotate($original_image,180,0);
break;
case 6:
$original_image = imagerotate($original_image,-90,0);
break;
}
}
$original_width = imagesx($original_image);
$original_height = imagesy($original_image);
$ratio = $max_resolution/$original_width;
$new_width = $max_resolution;
$new_height = $original_height * $ratio;
if($new_height > $max_resolution){
$ratio = $max_resolution / $original_height;
$new_height = $max_resolution;
$new_width = $original_width * $ratio;
}
if($original_image){
$new_image = imagecreatetruecolor($new_width,$new_height);
imagecopyresampled($new_image, $original_image, 0, 0, 0, 0,$new_width, $new_height, $original_width, $original_height);
imagejpeg($new_image,$newbfile,100);
imagedestroy($original_image);
imagedestroy($new_image);
}
}
}
When I check the resized image the Orientation information is gone from exif data however the original image I have uploaded did had the Orientation information. I am not sure what i am missing or doing wrong. Can someone help me with this?
Instead of doing the 2 part (resize and rotate) in one function, I made two functions one for rotation created by Wes and then for resize. First called the rotation function and then resize function.
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.
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.
So I've got this PHP script to scale and crop into a square from the center;
<?PHP
//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);
}
//usage example
resize_crop_image(100, 100, "test.jpg", "test.jpg");p_image(100, 100, "test.jpg", "test.jpg");
?>
You can simply call the following function:
resize_crop_image(100, 100, "test.jpg", "test.jpg");p_image(100, 100, "test.jpg", "test.jpg");
Added to JSFiddle is my HTML5/JQuery preview file before uploading to the server.
1). Do I need to upload the image to the server before running this script?
2). If needing to prior upload, how can I use my form to upload into a temp location, do the job and move to a specific dir and delete the temp dir?
1) Yes, a copy of the image will need to be on server before you can edit/crop it. 2) Uploaded files are automatically stored in the temp directory (they are usually copied out to use the image, but don't have to be). They can be read as an image from the temp directory by your code and PHP will also automatically clean up the file at the end of the script.
When a file gets uploaded, in the $_FILES array there is a key with the tmp name. You can just pass that into your function as the source file and it should work with imagecopyresampled with no issue. The temp name will be something like $_FILES['nameFromFileFieldOnForm']['tmp_name'].
if your source file or destination file is
$source_file = www.example.com/storage/packages/image.jpg
change it to
$source_file = ./storage/packages/image.jpg
It works for me in laravel 5
When resizing some png images they appear stretched and have what looks like vertical interlacing. I'm unsure of where the issue could be, however I'm starting to think its because the image starts in grayscale and needs to have a different color profile.
Any help or suggestions would be greatly appreciated.
Original image
Image showing the problem
function createImageSize($sourcefile, $setNewName, $maxwidth, $maxheight, $quality){
$fileInfoArray = #getimagesize($sourcefile);
$imagetype = $fileInfoArray['mime'];
list($width, $height, $attr) = getimagesize($sourcefile);
switch($imagetype){
case 'image/jpeg':
$img = imagecreatefromjpeg($sourcefile);
break;
case 'image/gif':
$img = imagecreatefromgif($sourcefile);
break;
case 'image/png':
$img = imagecreatefrompng($sourcefile);
break;
case 'image/x-png':
$img = imagecreatefrompng($sourcefile);
break;
}
if ($width > $maxwidth || $height > $maxheight){
if ( $width > $height ){
$newwidth = $maxwidth;
$ratio = $maxwidth / $width;
$newheight = floor($height * $ratio);
if ($newheight > $maxheight){
$newheight = $maxheight;
$ratio = $maxheight / $height;
$newwidth = floor($width * $ratio);
}
}else{
$newheight = $maxheight;
$ratio = $maxheight / $height;
$newwidth = floor($width * $ratio);
if ($newwidth > $maxwidth){
$newwidth = $maxwidth;
$ratio = $maxwidth / $width;
$newheight = floor($height * $ratio);
}
}
}else{
$newwidth = $width;
$newheight = $height;
}
$tmpimg = imagecreatetruecolor( $newwidth, $newheight );
if($imagetype == 'image/png'||$imagetype == 'image/x-png'){
imagealphablending($tmpimg, false);
imagesavealpha($tmpimg, true);
if($imagetype == 'image/gif'){
$transparent = imagecolorallocatealpha($tmpimg, 0, 0, 0, 127);
imagecolortransparent($tmpimg, $transparent);
}
imagefilledrectangle($tmpimg, 0, 0, $newwidth, $newheight, $transparent);
}
imagecopyresampled( $tmpimg, $img, 0, 0, 0, 0, $newwidth, $newheight, $width, $height );
switch($imagetype){
case 'image/jpeg':
imagejpeg($tmpimg, $setNewName, $quality);
break;
case 'image/gif':
imagegif($tmpimg, $setNewName);
break;
case 'image/png':
imagepng($tmpimg, $setNewName, 3);
break;
case 'image/x-png':
imagepng($tmpimg, $setNewName, 3);
break;
}
imagedestroy($tmpimg);
imagedestroy($img);
}
I had the same problem. While generating EPS files into transparent PNG files (to use as mask images later), iMagick created the PNG files as grayscale. When GD reads grayscale PNGs, it doubles them horizontally with vertical lines in them.
My solution was handled on the iMagic side, by forcing it to write the PNGs as RGBA:
before:
$image->setImageFileName("image.png");
After:
$image->setImageFileName("png32:image.png");
I don't know where your grayscale PNGs are coming from, but if you are generating them, make sure they are created RGBA. Otherwise perhaps there is a way to read them with GD properly, specifying grayscale source.
I have the same issue and still haven't found any solutions. It would seem that GD doesn't like grayscale PNG8 images and is interpreting as colored.
I may have to convert the image back to 24 bits using "convert" with exec() and then delete the image, but it's far from optimal.