Get image in storage in Laravel 5.2 - php

I have an image in storage->app->upload->images->1472803410756.jpg. When I type url http://localhost:8012/demo/storage/app/upload/images/1472803410756.jpg, browser show my image exactly. But run with php artisan serve, url: http://localhost:8000/storage/app/upload/images/1472803410756.jpg browser not found my image. How can fix it?
My html code:
<td><img class="table_image" src="{{asset("storage/app/upload/images/$product->product_image")}}"></td>

This is wrong way you get the image from storage folder.Because storage folder having only write permissions. So, Firstly you need to create the route of storage path
enter code here
Route::get('storage/{filename}', function ($filename)
{
$path = storage_path('app/upload/images/' . $filename);
if (!File::exists($path)) {
abort(404);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
After that your img tag look like this:-
<td><img class="table_image" src="{{url("storage/".$product->product_image)}}"></td>
Hope it helps!

Related

How to return json response and Storage data together in Laravel?

I'm trying to return query data and storage Images from laravel controller. My code looks like following :
class ClaimController extends Controller{
.....
public function show(Claim $claim)
{
$front_image = Storage::disk('do_spaces')->get($claim->images->front_image); //image file
$back_image = Storage::disk('do_spaces')->get($claim->images->back_image); //image
// return $front_image [works]
$claim = Claim::all();
//this throws error
return response()->json([
'claim' => $claim,
'images' => [$front_image, $back_image]
]);
}
}
Now I far I understand return->response()->json([]) doesn't send image file. How I can return all data together to frontend app ?
you have the option to return the images from original server which they are stored in or you can return an encoded version of the image as string and in front end reconstruct it.
$path = 'myfolder/myimage.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
And then use it in front like this :
var image = new Image();
image.src = 'data:image/png;base64,iVBORw0K...';
document.body.appendChild(image);
This is the link for second part.
You can use Storage::url()
$st=\Illuminate\Support\Facades\Storage::disk('do_spaces')->url($claim->images->front_image);
dd(url($st));
Storage::url() return image path and then url() will return full url path
"http://127.0.0.1:8000/storage/imagefolder/filename"
Make sure to symbolic link to storage folder by running following command
php artisan storage:link
Also you can do the following without storage url
asset('storage/'.$claim->images->front_image)

Laravel fail to return image

I've a image and some text file in storage folder other than the public folder. the folder architecture is
storage
|->uploads
and set a route like
Route::get('storage/{folder}/{filename}','FileController#getFile');
inside the Controller the getFile method have following code
$path = storage_path($folder . DIRECTORY_SEPARATOR . $filename);
if (extension_loaded('fileinfo')) {
if (!File::exists($path)) {
abort(404);
}
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
}
else{
abort(412,'please enable the fileinfo extension or contact site administration');
}
when i try to retrieve the image from url it return the blank image like this
blank image
but when i try to retrive the text file it return the file
Also tried it with Image::make($path) and response()->file($path) when the mime type is image/* still the output is same..
so How do i show my image file from url without using the public folder
This is how i do it... I also check for user permissions but i adapted it to your needs...
public function getFile()
{
$path = storage_path($folder . DIRECTORY_SEPARATOR . $filename);
return response()->file($path);
}

Display the image files from the storage

I'm on Laravel 5.3 and I'm having trouble rendering the file images from Laravel Storage to my html/blade.
My filesystems.php default driver
'default' => 'public'
How to render the file images from the 'Storage' to view/html/blade
I tried this,
//path for image from the storage
Route::get('/app/system/sale-items/item/{username}/{item_id}/{image}', function($image,$item_id,$username)
{
$path = storage_path().'/app/public/'.$username.'/'.$item_id.'/'. $image;
if (file_exists($path)) {
return Response::download($path);
}
});
but seem's not working like the image is not showing, it fails to retrieved the image from the 'Storage'. Any help, ideas please?
I figured it out already, I just use
//path for image from the storage
Route::get('/app/system/sale-items/item/{username}/{item_id}/{image}', function($username,$item_id,$image)
{
$path = storage_path().'/app/public/'.$username.'/'.$item_id.'/'. $image;
if (file_exists($path)) {
return Response::download($path);
}
});

Laravel Access Images outside public folder

I need to store images in a backend for logged in users. The stored images need to be protected and not visible from the outside (public). I choosed a "storage" folder for this.
I came up with this in my Controller:
public function update(Request $request, $id)
{
//Show the image
echo '<img src="'.$_POST['img_val'].'" />';
//Get the base-64 string from data
$filteredData=substr($_POST['img_val'], strpos($_POST['img_val'], ",")+1);
//Decode the string
$unencodedData=base64_decode($filteredData);
//Save the image
$storagepath = storage_path('app/images/users/' . Auth::user()->id);
$imgoutput = file_put_contents($storagepath.'/flyer.png', $unencodedData);
return view('backend.flyers.index')->withImgoutput($imgoutput)
//->withStoragepath($storagepath);
}
after hitting the save button, which triggers the update() I am able to see the image in my view, and it is also stored in my folder (current users=10) "storage/app/images/users/10/flyer.png"
my question is how can I access the image path?
I want to show the stored image with img src="">. I have no idea what to put inside "src= ..."
While dealing with user file uploads in web applications, the major aspect is about user's content's security.
One should use secure way to upload private files of a user in web applications.
As in your case, you want to access user's image outside public folder.
This can be done in a most secure way as given below.
First of all create a directory right in the root directory of Laravel (where the public folder is located), let the directory's name be uploads. Use this directory to upload private user files.
In the case of images create an another directory inside uploads as uploads/images/ inside uploads directory so that you can have a different storage locations for different type of files.
Remember to upload the image in images directory with a different name and without their extensions so that it looks like a extension-less file.
Keep the file name and its extension in the database which can be used later to retain image's location.
Now you need to create a separate route to show user's image.
Route::get('users/{id}/profile_photo', 'PhotosController#showProfilePhoto')->name('users.showProfilePhoto');
PhotosController.php
class PhotosController extends Controller {
private $image_cache_expires = "Sat, 01 Jan 2050 00:00:00 GMT";
public function showProfilePhoto($id) {
$user = User::find($id);
$path = base_path() . '/uploads/images/';
if($user && $user->photo) // Column where user's photo name is stored in DB
{
$photo_path = $path . $user->photo; // eg: "file_name"
$photo_mime_type = $user->photo_mime_type; // eg: "image/jpeg"
$response = response()->make(File::get($photo_path));
$response->header("Content-Type", $photo_mime_type);
$response->header("Expires", $this->image_cache_expires);
return $response;
}
abort("404");
}
}
The method above inside PhotosController - showProfilePhoto($user_id) will run as soon as you access the route named - users.showProfilePhoto.
Your HTML code will look like this.
<img src="<?php echo route('users.showProfilePhoto', array('id' => $user->id)); ?>" alt="Alter Text Here">
The above code will work like a charm and the image will be shown to the user without declaring/publishing the proper image path to public.
According to me this is the secure way to deal with file uploads in web applications.
You can do this like this:
Route::get('images/{filename}', function ($filename)
{
$path = storage_path() . '/' . $filename;
if(!File::exists($path)) abort(404);
$file = File::get($path);
$type = File::mimeType($path);
$response = Response::make($file, 200);
$response->header("Content-Type", $type);
return $response;
});
Reference:
Laravel 5 - How to access image uploaded in storage within View?
Or Alternatively you can use this library: https://github.com/thephpleague/glide
Just use composer to install it in your project
By default, this will render images from your storage, and allow you to do all sorts of things with it such as cropping, color correction etc.
Reference:
http://glide.thephpleague.com/
https://laracasts.com/discuss/channels/laravel/laravel-5-how-can-we-access-image-from-storage?page=1
Atimes you might have some images you do not wish to store in public directory for some various reasons.
Although storing your images has lots of advantages.
There are many ways you can achieve this, however I have this simple solution.
You should create a helper class like so if already don't have one
<?php namespace App\Services;
class Helper
{
public function imageToBase64($path)
{
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
return 'data:image/' . $type . ';base64,' . base64_encode($data);
}
}
Then in your view (blade)
#inject('helper', 'App\Services\Helper')
<img width="200" height="250" src="{{$helper->imageToBase64(storage_path('app/images/users/' . Auth::user()->id)}}">
It will work 100% work. Open file filesystem in app/config/filesystem.php and write like that
'profile' => [
'driver' => 'profile',
'root' => '/home/folder/public_html/projectname/public/profiles',
],
Add this file at top
use Illuminate\Support\Facades\Storage;
My variable name is
$directoryName = 'profile';
$imageName = $request->image; // image is array of base64 encoded urls
$directory_path ='profiles';
Below function save your file in public/profiles folder.
function UploadImagesByBase64($directoryName, $imageName,$directory_path)
{
$data = array();
$image = $imageName;
foreach ($image as $image_64) {
if($image_64 !=null){
$extension = explode('/', explode(':', substr($image_64, 0, strpos($image_64, ';')))[1])[1]; // .jpg .png .pdf
$replace = substr($image_64, 0, strpos($image_64, ',')+1);
// find substring fro replace here eg: data:image/png;base64,
$image = str_replace($replace, '', $image_64);
$image = str_replace(' ', '+', $image);
$imageName = Str::random(10).time().'.'.$extension;
Storage::disk($directoryName)->put($imageName, base64_decode($image));
$data[] = $directory_path.'/'.$imageName;
}
}
$imageName = implode(',', $data);
return $imageName;
}

Resizing an image before displaying it in the browser

I'm creating an API in which I have a model called OnlineAds(), it has these columns title, full_discription, short_discription and image, I also created an input form to fill in these fields and upload an image, in the image field I add the image's name and store the image in this path: storage/uploads. I was able to retrieve the image and display it, but I still didn't figure out how to resize it before displaying (lets say I want it to be 300 x 300), can anybody show me how ?
Note: I tried to use Stapler and Imagine but they seemed to give multiple bugs and failed!
This is my controller:
public function show()
{
$img = OnlineAds::find(50)->image;
$path = storage_path('uploads') . '/' . $img;
if (File::exists($path)) {
$filetype = File::type($path);
$response = Response::make(File::get($path), 200);
$response->header('Content-Type', $filetype);
return $response;
}
}
You could look into using Intervention to take care of the image processing as well as handling the response. It can be as easy as this:
public function show()
{
$img = OnlineAds::find(50)->image;
$path = storage_path('uploads') . '/' . $img;
if (File::exists($path)) {
$img = Image::make($path);
$img->resize(300, 300);
return $img->response();
}
}
There are detailed instructions on how to install the Intervention library and integrate it with Laravel, and it shouldn't take more than a few minutes to get it up and running.

Categories