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.
Related
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 :)
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.
First, I'm not master of PHP. I'm using a function for resize and crop images. It's working perfectly until I upload a transparent png. :)
It saves the png with black background. I found some answers on stackoverflow but I can't combine it with my codes.
Here is my function:
//resize and crop image
function resize_crop_image($max_width, $max_height, $source_file, $dst_dir, $quality = 90){
$imgsize = getimagesize($source_file);
$width = $imgsize[0];
$height = $imgsize[1];
$mime = $imgsize['mime'];
switch($mime){
case 'image/gif':
$image_create = "imagecreatefromgif";
$image = "imagegif";
$format = "gif";
break;
case 'image/png':
$image_create = "imagecreatefrompng";
$image = "imagepng";
$quality = 7;
$format = "png";
break;
case 'image/jpeg':
$image_create = "imagecreatefromjpeg";
$image = "imagejpeg";
$format = "jpg";
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);
}
// you can ignore these 4 lines. I'm using it for change the name.
$nameforimage = rand('11111111', '9999999999');
$nameforimage2 = rand('11111111', '9999999999');
$newname = $nameforimage."_".$nameforimage2;
$newdir = $dst_dir."".$newname.".".$format;
$image($dst_img, $newdir, $quality);
if($dst_img)imagedestroy($dst_img);
if($src_img)imagedestroy($src_img);
return $newname.".".$format;
}
EDIT:
Okay I've found a solution.
Just add these lines:
imagealphablending($dst_img, false);
imagesavealpha($dst_img, true);
$transparent = imagecolorallocatealpha($dst_img, 255, 255, 255, 127);
imagefilledrectangle($dst_img, 0, 0, $max_width, $max_height, $transparent);
After this line:
$dst_img = imagecreatetruecolor($max_width, $max_height);
You have to enable saving the alpha channel.
It can be done with imagesavealpha(), e.g.:
// As per the manual, alpha blending must be disabled
imagealphablending($dst_img, false);
imagesavealpha($dst_img, true);
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
I'm using some PHP code from jquery file upload and I'm trying to rotate an image prior to saving it. Below is my function call:
public function CreateThumb($file_name, $options){
$file_path = $options['src_dir'].$file_name;
$new_file_path = $options['dst_dir'].$file_name;
list($img_width, $img_height) = #getimagesize($file_path);
if (!$img_width || !$img_height) {
return false;
}
$scale = min(
$options['max_width'] / $img_width,
$options['max_height'] / $img_height
);
$new_width = $img_width * $scale;
$new_height = $img_height * $scale;
$new_img = #imagecreatetruecolor($new_width, $new_height);
switch (strtolower(substr(strrchr($file_name, '.'), 1))) {
case 'jpg':
case 'jpeg':
$src_img = #imagecreatefromjpeg($file_path);
$write_image = 'imagejpeg';
$image_quality = isset($options['jpeg_quality']) ?
$options['jpeg_quality'] : 95;
break;
case 'gif':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
$src_img = #imagecreatefromgif($file_path);
$write_image = 'imagegif';
$image_quality = null;
break;
case 'png':
#imagecolortransparent($new_img, #imagecolorallocate($new_img, 0, 0, 0));
#imagealphablending($new_img, false);
#imagesavealpha($new_img, true);
$src_img = #imagecreatefrompng($file_path);
$write_image = 'imagepng';
$image_quality = isset($options['png_quality']) ?
$options['png_quality'] : 9;
break;
default:
$src_img = null;
}
$src_img = imagerotate($src_img, 90, 0) ;
$success = $src_img && #imagecopyresampled(
$new_img,
$src_img,
0, 0, 0, 0,
$new_width,
$new_height,
$img_width,
$img_height
) && $write_image($new_img, $new_file_path, $image_quality);
// Free up memory (imagedestroy does not delete files):
#imagedestroy($src_img);
#imagedestroy($new_img);
return $success;
}
The image gets rotated but it still maintains it's original aspect ratio and is cropping the photo. Any idea what I'm doing wrong?
Your problem is in how you set the new values:
$new_width = $img_width * $scale;
$new_height = $img_height * $scale;
Should be, in case of a 90 degrees rotation:
$new_width = $img_height * $scale; // reverse height and width
$new_height = $img_width * $scale; // reverse height and width
Edit: And as the original image is rotated, the old width and height have to be reversed:
$success = $src_img && #imagecopyresampled(
$new_img,
$src_img,
0, 0, 0, 0,
$new_width,
$new_height,
$img_height, // reverse width and height
$img_width // reverse width and height
) && $write_image($new_img, $new_file_path, $image_quality);
Just a note: if you are going to use that many #'s to ignore errors, you might as well just put error_reporting(0); at the start of the code.
Secondly, the reason that I saw for the lack of change in pixel ratio is because your $scale is backwards. You have it saying scale = Whole/Part which will almost always give you a value greater than 1 (increasing pixel ratio) unless the max size is smaller than the image size. You'll want it to be scale = Part/Whole So its a decimal ratio (ie 100px/400px, scale = .25).
Good Luck!