Default image upload process in my app like this.
Get image from request and store it to s3 and a local variable.
$path = $request->file("image")->store("images", "s3");
After this I make it public.
Storage::disk("s3")->setVisibility($path, 'public');
And store to DB like this.
$variable = ModelName::create([
"image" => basename($path),
"image_url" => Storage::disk("s3")->url($path),
But how to resize the image before store it to s3?
I try to write like this
$extension = $request->file('image')->getClientOriginalExtension();
$normal = Image::make($request->file('image'))->resize(160, 160)->encode($extension);
$filename = md5(time()).'_'.$request->file('image')->getClientOriginalName();
$img = Storage::disk('s3')->put('/images/'.$filename, (string)$normal, 'public');
And then
"image" => basename($filename ),
"image_url" => Storage::disk("s3")->url($img),
This works except one thing. I can't get URL (to store DB) for uploaded image.
How to get correct public url for uploaded image?
Note:I use Intervention Image package
Storage::put() would only return the path if it's an instance of File or UploadedFile (source). In this case $normal isn't, so put() would return a boolean instead. Also, using getClientOriginalExtension() probably isn't a good idea since it's not considered a safe value (source).
So here's a bit improved version:
$filename = $request->file('file')->hashname();
$image = Image::make($request->file('file'))->resize(160, 160);
Storage::disk('s3')->put('/images/'.$filename, $image->stream(), 'public');
$url = Storage::disk('s3')->url('/images/'.$filename);
You can now save $url and $filename into your db.
You can try my code snippet.
$file = $request->file('image');
$fileName = md5(time()).'.'.$file->getClientOriginalExtension();
/** #var Intervention $image */
$image = Image::make($file);
if ($image->width() > ($maxWidth ?? 500)) {
$image = $image->resize(500, null, function ($constraint) {$constraint->aspectRatio();});
}
$image = $image->stream();
try {
/** #var Storage $path */
Storage::disk('s3')->put(
$dir . DIRECTORY_SEPARATOR . $fileName, $image->__toString()
);
} catch (\Exception $exception) {
Log::debug($exception->getMessage());
}
Related
i am using a function that uploads multiple images and it was working perfectly locally but after deployment i am having this duplication issue .
i upload img1 and img2 and img3 but in the database i find only one of them like img1.jpg and the same thing in the folder .
public function _articleGalleryUpload(Request $request)
{
$article = Blog::find($request->id);
$img = $request->Otitle;
//dd($img);
$request->validate([
'images'=> 'required',
'images.*'=> 'image|mimes:jpg,png,jpeg|max:4000'
]);
if(!File::isDirectory('assets/images/blogs/gallery/'.$img)){
File::makeDirectory('assets/images/blogs/gallery/'.$img);
}
$images = $request->file('images');
if($request->hasFile('images'))
{
foreach( $images as $image )
{
//$extension = $file->getClientOriginalExtension();
$ImageName = '_' . time() .'.' . $image->getClientOriginalExtension();
$path = $image->move(('assets/images/blogs/gallery/'.$img), $ImageName);
$imageP = Image::make($path)->resize(600, null, function ($constraint) {
$constraint->aspectRatio();
});
$galerie = new blogsGallery;
$galerie->Img = $ImageName;
$galerie->idart = $request->id;
$galerie->alt = $img;
$imageP->save();
$galerie->save();
}
return back()->with('success', 'les images ont été téléchargées');
}
}
i tried using array to store the names of the images but it didn't work, it uploads one image instead of multiple .
Your code has one issue.
$path = $image->move(('assets/images/blogs/gallery/'.$img), $ImageName);
this code is error.
$img is one name for several images.
I am trying to store image into database after it has been converted to base64 and also decoded. The image stores inside the Storage path but does not save into mysql database.
What am i doing wrong?
public function updateProfileImage(Request $request)
{
$user = auth('api')->user();
$image = $request->input('image'); // image base64 encoded
preg_match("/data:image\/(.*?);/",$image,$image_extension); // extract the image extension
$image = preg_replace('/data:image\/(.*?);base64,/','',$image); // remove the type part
$image = str_replace(' ', '+', $image);
$imageName = 'profile' . time() . '.' . $image_extension[1]; //generating unique file name;
Storage::disk('public')->put($imageName,base64_decode($image));
$user->update($request->all());
}
Try this:
$user = auth('api')->user();
if ($request['image']) {
$data = $request['image'];
list($type, $data) = explode(';', $data);
list(, $data) = explode(',', $data);
$image = base64_decode($data);
$photoName = 'profile' . time() . '.' . $image_extension[1];
$request['image'] = $photoName;
Storage::disk('public')->put($photoName, $image);
$user->update($request->all());
}
I had to do this
public function updateProfileImage(Request $request)
{
$user = auth('api')->user();
$image = $request->input('image'); // image base64 encoded
preg_match("/data:image\/(.*?);/",$image,$image_extension); // extract the image extension
$image = preg_replace('/data:image\/(.*?);base64,/','',$image); // remove the type part
$image = str_replace(' ', '+', $image);
$imageName = 'profile' . time() . '.' . $image_extension[1]; //generating unique file name;
Storage::disk('public')->put($imageName,base64_decode($image));
$user->update($request->except('image') + [
'profilePicture' => $imageName
]);
}
and it worked
I recommend you to use uploader packages like:
https://github.com/spatie/laravel-medialibrary
or
https://github.com/alaaelgndy/FileUploader
to help you in media management without writing all these lines of code in every place you want to upload files.
enjoy them.
I'm uploading an image to S3 with Laravel as follows:
$image = $request->image;
if (!empty($image)) {
$imageFileName = $user_id.'_'.rand(11111111, 99999999) . '.' . $image->getClientOriginalExtension(); // Rename Image
try
{
//Send to S3
$s3 = Storage::disk('s3');
$filePath = '/profile/' . $imageFileName;
$s3->put($filePath, file_get_contents($image), 'public');
$image = Storage::cloud()->url($imageFileName);
}
catch(\Exception $exx)
{
//Send to Logs Etc
}
The image uploads successfully but I need to store the URL in my database. This is being called here:
$image = Storage::cloud()->url($imageFileName);
The issue is the URL being returned, it looks like this:
http://test-env.XXX.us-west-2.elasticbeanstalk.com/profile/https://elasticbeanstalk-us-west-2-123XXX456XXX.s3.us-west-2.amazonaws.com/6_52644340.jpg
Hence:
http://mentr-test-env.2w8sh3esch.us-west-2.elasticbeanstalk.com/profile/
is somewhat-correct. But the next piece is missing the 'profile' sub-folder, and obviously starts at HTTPS again:
https://elasticbeanstalk-us-west-2-123XXX456XXX.s3.us-west-2.amazonaws.com/6_52644340.jpg
It would appear I'm getting two halves of the link in a single string. I don't edit the $image variable anywhere else.
The correct link is:
https://elasticbeanstalk-us-west-2-123XXX456XXX.s3.us-west-2.amazonaws.com/profile/6_52644340.jpg
I have confirmed the files are uploading correctly and publicly available.
I have tried calling:
$image = Storage::cloud()->url($filePath);
And this returns:
http://test-env.XXXX.us-west-2.elasticbeanstalk.com/profile/https://elasticbeanstalk-us-west-2-XXX123XXX.s3.us-west-2.amazonaws.com//profile/6_31595766.jpg
Update
I just noticed the first part of the returned URL is the BeanStalk instance URL with the /profile/ added. This is even stranger as I don't wish to use Beanstalk, I only want to use S3.
If you want to store the entire url you can get it from the return variable passed back from the put() function.
$s3_url = $s3->put($filePath, file_get_contents($image), 'public');
Sometimes I like to just store the path though and save just that piece to the database then I can pass the path to Storage::url($filePath); and it still works.
$image = $request->image;
if (!empty($image)) {
$imageFileName = $user_id.'_'.rand(11111111, 99999999) . '.' . $image->getClientOriginalExtension(); // Rename Image
try
{
//Send to S3
$s3 = Storage::disk('s3');
$filePath = '/profile/' . $imageFileName;
$s3->put($filePath, file_get_contents($image), 'public');
$image = Storage::cloud()->url('s3-url/s3-bucket'.'/'.$filepath);
}
catch(\Exception $exx)
{
//Send to Logs Etc
}
I try to store a user avatar in the October CMS database after resizing it with intervention image package I use this code:
if (Input::hasFile('avatar')) {
$file= $user->avatar;
$filenamewithextension = $file->getClientOriginalName();
//get filename without extension
$filename = pathinfo($filenamewithextension, PATHINFO_FILENAME);
//get file extension
$extension = $file->getClientOriginalExtension();
//filename to store
$filenametostore = $filename.'_'.uniqid().'.'.$extension;
Storage::put('public/profile_images/'. $filenametostore, fopen($file, 'r+'));
Storage::put('public/profile_images/thumbnail/'. $filenametostore, fopen($file, 'r+'));
//Resize image here
$thumbnailpath ='storage/app/public/profile_images/thumbnail/'.$filenametostore;
$img = Image::make($file->getRealPath());
$img->crop(request('w'), request('h'), request('x1'), request('y1'));
$img->save($thumbnailpath);
$user->avatar=$filenametostore;
}
but I get an error:
Call to undefined method October\Rain\Database\QueryBuilder::getClientOriginalName()
can anyone help me please?!
You are calling getClientOriginalName() on the wrong object, try changing the following lines in your code to this:
if (Input::hasFile('avatar')) {
$file = Input::file('avatar');
/* ... */
Storage::put('public/profile_images/'. $filenametostore, fopen($file->getRealPath(), 'r+'));
Storage::put('public/profile_images/thumbnail/'. $filenametostore, fopen($file->getRealPath(), 'r+'));
/* ... */
}
Following a tutorial I did this:
public function store(Request $request)
{
$file = Input::file('imagen1');
$image = \Image::make(\Input::file('imagen1'));
$path = public_path().'/thumbnails/';
$image->save($path.$file->getClientOriginalName());
$image->resize(null, 300, function ($constraint) {
$constraint->aspectRatio();
});
$image->save($path.'thumb_'.$file->getClientOriginalName());
$thumbnail = new Thumbnail();
$thumbnail->image = $file->getClientOriginalName();
$thumbnail->save();
$request->user()->propiedades()->create($request->all());
return redirect('profile#propiedades');
}
And my problem is that the image is being save in a "temporal" path and not the real one. So when i go to my table 'Propiedades' It just shows this:
The right direction is this one
So my question is how do i make intervention image saves the real path? Thanks in advance
UPDATE
Ok. Now thanks to Nazmul Hasan i am seeing this in my database.
The only thing left is that it saves the name of the file. So i can go to my blade and do {{ $propiedades->imagen1 }}
Thanks!!
UPDATE 2
$file = Input::file('imagen1');
$ext = time() . '.' . $file->getClientOriginalExtension();
$path = public_path('thumbnails/' . $ext);
$image = \Image::make(\Input::file('imagen1'));
$image->save($path.$file->getClientOriginalName());
$image->resize(400, null, function ($constraint) {
$constraint->aspectRatio();
});
$image->save($path.'thumb_'.$file->getClientOriginalName());
$thumbnail = new Thumbnail();
$thumbnail->image = $file->getClientOriginalName();
$thumbnail->save();
$inputs = $request->all();
$inputs['imagen1'] = $path;
$request->user()->propiedades()->create($inputs);
return redirect('profile#propiedades');
AND NOW IT SAVES RIGHT THE IMG PATH BUT THE IMAGE IS NOT BEING SAVE CORRECLTY
Your problem is in this line
$request->user()->propiedades()->create($request->all());
You does not update image upload path in $request variable
For this reason $request->all() save temporary image path
You can try this
$file = Input::file('imagen1');
$image = \Image::make(\Input::file('imagen1'));
$path = public_path().'/thumbnails/';
$image->save($path.$file->getClientOriginalName());
$image->resize(null, 300, function ($constraint) {
$constraint->aspectRatio();
});
$image->save($path.'thumb_'.$file->getClientOriginalName());
$thumbnail = new Thumbnail();
$thumbnail->image = $path.'thumb_'.$file->getClientOriginalName();
$thumbnail->save();
$inputs = $request->all()
$inputs['imagen1'] = $path.$file->getClientOriginalName();
$request->user()->propiedades()->create($inputs);
return redirect('profile#propiedades');