Upload an image and create its thumbnail Laravel 5.2 - php

So yesterday I tried to make an upload file function , for when user makes his products, he can also upload a picture too.
But the picture was too big when I was iterating through the items, so I decided to use intervention package to resize the picture and also create a thumbnail picture.
I made the function but its partially working.
if($file = $request->hasFile('image')) {
$file = $request->file('image');
$extension = $file->getClientOriginalName();
$username = Auth::user()->username;
$destinationPath = public_path('/uploads/products/' . $username);
$thumb = Image::make($file->getRealPath())->resize(100, 100, function ($constraint) {
$constraint->aspectRatio(); //maintain image ratio
});
$thumb->save($destinationPath.'/thumb_'.$extension);
$destinationPath = public_path('/uploads/products/' . $username);
$file->move($destinationPath, $extension);
$product['imagePath'] = '/uploads/products/'. $username . '/' . $extension;
$product['thumbnail'] = '/uploads/products/'. $username . '/thumb_' . $extension;
}
I made it so, different user will create a different file in /uploads/products.
Also I upload the original picture and the resized so the I should have like:
picture.jpg and thumb_picture.jpg.
When the custom file is not created (from the name of the user) I get this error:
Can't write image data to path
(C:\xampp\htdocs\shop\public/uploads/products/book/thumb_Jellyfish.jpg)
When I comment 6,7,8 lines, the function works but it uploads only the original picture as it supposed to. If I remove the comment, the thumbnail works too!
So I guess, after the custom folder has been created, the whole function works fine, but before it has a writable problem.
Any ideas? Everything will be appreciated!

For anyone wonder how to fix this or do something similar, I just found the solution:
if($file = $request->hasFile('image')) {
$file = $request->file('image');
$extension = $file->getClientOriginalName();
$username = Auth::user()->username;
$thumb = Image::make($file->getRealPath())->resize(100, 100, function ($constraint) {
$constraint->aspectRatio(); //maintain image ratio
});
$destinationPath = public_path('/uploads/products/' . $username);
$file->move($destinationPath, $extension);
$thumb->save($destinationPath.'/thumb_'.$extension);
$product['imagePath'] = '/uploads/products/'. $username . '/' . $extension;
$product['thumbnail'] = '/uploads/products/'. $username . '/thumb_' . $extension;
}
So this piece of code makes a dynamic folder (I chose the username of the authenticated user) inside /uploads/products/. In that folder it uploads the picture and also creates a resized one, for thumbnail use. Also, when it creates the thumbnail, it holds the ratio of the original picture so it doesn't lose proportions

Related

How to get Interventation/Image after Resize in Laravel

I used Interventation image to resize a big size uploaded image. But I don't want to save it into the local directory of Laravel. This is my sample source code.
public function Uploader(Request $request) {
$upload_file = $request->file_upload;
$new_img = Image::make($upload_file)->resize(800, 544);
$new_img->save(\public_path($fileName));
$upload_file_new = "../public/" . $fileName;
}
I want to get the new path of the resized image (by not by saving it). I used
$path = $new_img->basePath();
But it returns the basePath of the $upload_file. How can I get the new path so I can use it on fopen($upload_file_new, 'r'). Please help. Thank you.
you can do like this
$image_new_name = time() . str_random(10) . str_replace(' ','',$upload_file->getClientOriginalName());

Laravel and Intervention Image getSize() error

I'm trying to integrate Intervention/Image into my laravel project to create a thumbnail upon uploading an image.
The image upload itself works fine, it doesn't seem to have any issue recognizing Intervention itself.
Below is the code block. The error seems to happen on the line with the save statement, I'm able to die and dump the contents of $img after it's set.
$file = $request->file('image');
$name = md5($file->getClientOriginalName() . time());
$extension = $file->getClientOriginalExtension();
$fileName = $name . '.' . $extension;
$file->move('./uploads/images/', $fileName);
$img = Image::make($file)->fit(300);
$img->save('/uploads/thumbnails/' . $name, 60, 'jpg');
This is the error I'm getting:
SplFileInfo::getSize(): stat failed for /private/var/folders/87/p5x7mgy914qg9ytf2zccc6q00000gn/T/php3lshFS
After some searching I've found that this could be related to file size upload limits, but I've altered my php.ini file (all of this is local btw) to accept 20MB files and the file I'm trying to upload is less than 100kb. I've also reset both php through homebrew and apache. Still getting the error.
Is there any glaringly obvious issues in my use of Intervention? I'll happily provide more info, this is in the store function in one of my controllers btw.
Untested, but I do it like this:
public function thumbnail(Request $request){
$thumbDir= storage_path('app/public').'/uploads/thumbnails/';
$file = $request->file('image');
$filename = md5($file->getClientOriginalName() . time()).'.jpg';
// $name = md5($file->getClientOriginalName() . time());
// $extension = $file->getClientOriginalExtension();
// $fileName = $name . '.' . $extension;
// $file->move('./uploads/images/', $fileName);
Image::make($file)->encode('jpg', 60)->fit(300, null, function ($c) {
$c->aspectRatio();
$c->upsize();
})->save($thumbDir . $filename);
return back()->with('success','The Image Has Been Added.');
}

Using Intervention Image to resize an image in the storage folder

I have a function in my Laravel application that allows users to upload profile pictures to their profile.
Here is the method:
/**
* Store a user's profile picture
*
* #param Request $request
* #return void
*/
public function storeProfilePicture(User $user = null, Request $request)
{
$user = $user ?? auth()->user();
//Retrieve all files
$file = $request->file('file');
//Retrieve the file paths where the files should be moved in to.
$file_path = "images/profile-pictures/" . $user->username;
//Get the file extension
$file_extension = $file->getClientOriginalExtension();
//Generate a random file name
$file_name = Str::random(16) . "." . $file_extension;
//Delete existing pictures from the user's profile picture folder
Storage::disk('public')->deleteDirectory($file_path);
//Move image to the correct path
$path = Storage::disk('public')->putFile($file_path, $file);
// Resize the profile picture
$thumbnail = Image::make($path)->resize(50, 50, function ($constraint) {
$constraint->aspectRatio();
});
$thumbnail->save();
$user->profile()->update([
'display_picture' => Storage::url($path)
]);
return response()->json(['success' => $file_name]);
}
I am trying to use the Intervention Image library to resize the uploaded picture from the storage folder, but I always get the same error.
"Image source not readable", exception: "Intervention\Image\Exception\NotReadableException"
I have also tried with Storage::url($path) as well as storage_path($path)
Here below code work very well with the storage path, you can directly make thumb image from request and put anywhere as a desire path as follows.
Note that here I am not deleting previse stored files or directory as I am assuming that was done already.
$file = $request->file('file');
$path = "public/images/profile-pictures/{$user->username}/";
$file_extension = $file->getClientOriginalExtension();
$file_name = time(). "." . $file_extension;
// Resize the profile picture
$thumbnail = Image::make($file)->resize(50, 50)->encode($file_ext);
$is_uploaded = Storage::put( $path .$file_name , (string)$thumbnail ); // returns true if file uploaded
if($is_uploaded){
$user->profile()->update([
'display_picture'=> $path .$file_name
]);
return response()->json(['success' => $file_name]);
}
Happy coding

Image upload and resize function not working as it must

I have simple resize image function in my laravel project. It should upload original image and make thumbnail of it.
After form submitting I got two images but the original image is placed in wrong directory. This is the function in my controller
if (Input::hasFile('image') && !Input::get('remove_image')) {
$file = Input::file('image');
$filename = str_random(20);
$image = new ImageResize($file);
$original = $filename . '.'. $file->getClientOriginalExtension();
$thumb = $filename . '-thumb.' . $file->getClientOriginalExtension();
$file->move(public_path() . '/uploads', $original);
$imagePath = '/uploads/' . $original;
$thumbPath = '/uploads/' . $thumb;
$image->crop(200, 200);
$image->save('uploads/' . $thumb);
}
Basically when I upload image.jpg I get two images image.jpg and image-thumb.jpg. Both images should be save in uploads i.e. public/uploads/ BUT only thumbnail is saved there.
The original image is saved in **bootstrap**/uploads/. Why is going in bootstrap... directory? I didn't mentioned it anywhere?
You can try to replace the public_path() method to url('/'). Not sure this will help but I don't have good experiences with public_path()
Image::make($request->file('image'))->resize(462, 462)->save('upload_path/filename.jpg'));
Try This Code..
Use Image Intervention to resize and save the image
Image::make($avatar)->resize(250, 250)->save(public_folder('/uploads/'.$filename));
The resize function will resize the image and save function will save the image to uploads folder. Give a desired filename to $filename variable.
Leave only the directory to where you want to save the original. Try to change this line which is moving the image
$file->move(public_path() . '/uploads', $original);
with this one ( remove the public path )
$file->move('uploads', $original);

Detecting if user is uploading the same image

I have a form that contains an image upload and an input text box. The user will be able to upload an image and enter text without refreshing the page using Ajax. The image will be relayed to PHP and PHP will handle what to do with the image. My problem is that for the first time the user uploads an image, it'll be checked if the same image name is on the server or not. If it is, the image name will get a uniqid() and then will be uploaded. But what if the user changes the data in the text box field, but keeps the image? Then that image will be uploaded again with a uniqid() since it's already on the server. I've tried solving this using my current code for the image handling:
PHP
$target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name";
if (isset($_SESSION["size"]))
{
$prevSize = $_SESSION["size"];
if (filesize($prevSize) != filesize($size))
{
if (#getimagesize($target_file) == true)
{
$ext = pathinfo($name, PATHINFO_EXTENSION);
$name = basename($name, "." . $ext);
$name = $name . uniqid() . "." . $ext;
$target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name";
}
}
}
else
{
$_SESSION["size"] = $size;
if (#getimagesize($target_file) == true)
{
$ext = pathinfo($name, PATHINFO_EXTENSION);
$name = basename($name, "." . $ext);
$name = $name . uniqid() . "." . $ext;
$target_file = $_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/$name";
}
}
move_uploaded_file($tempName, $target_file);
Unfortunately, this code isn't working like I want it to. If I upload the same image twice in a row, in the same session, it doesn't override my previous image. Instead, it puts it on the server with a uniqid name. What am I doing wrong? And if there's a better way in solving this, I'd love to know!
What you can do is whenever someone uploads an image, store a hash of the image, encrypt it and store it in the database on the image row.
From now on, whenever someone uploads an image run a query like this:
SELECT COUNT(*) FROM images WHERE hash = $hash then in an if statement check if the returned value is bigger than 0, if it is, do what you need to do without re-uploading the image, and if it is 0, then upload your image and proceed
I chose a user avatar upload for this example. I'm not sure what your image is, but the workflow should be similar. No duplicate avatars will be copied to the image path.
function get_avatar_filename($filename) {
// only generate an avatar filename if the mimetype matches
switch (mime_content_type($filename)) {
case 'image/jpeg':
return sprintf('%s.jpg', hash_file('md5', $filename));
case 'image/gif':
return sprintf('%s.gif', hash_file('md5', $filename));
case 'image/png':
return sprintf('%s.png', hash_file('md5', $filename));
// otherwise the user uploaded a non-supported image
// return the default image
default:
return 'default-avatar.jpg';
}
}
function upload_avatar($avatarPath, $filename) {
// get the avatar filename
$f = get_avatar_filename($filename);
// copy the file to $avarPath only if the file doesn't already exist
if (!file_exists("{$avatarPath}/{$f}")) {
move_uploaded_file($filename, "{$avatarPath}/{$f}");
}
// return the avatar filename
return $f;
}
Now you can use these functions when you process the user form submission
// process user form submission ...
// ...
$filename = upload_avatar(
$_SERVER['DOCUMENT_ROOT'] . "/stories/media/images/",
$_FILES['user_avatar']['tmp_name']
);
// save the avatar location for the user ...
// or whatever
$user->setAvatar($filename);
$user->save();
If the user uploads a non-supported image type, they will just be assigned default-avatar.jpg which is a file that should exist in your images directory.

Categories