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)
Trying to retrieve an image from outside public. I have been using file controller helper but still can't get it to work:
here is my code that is returned as AJAX to update the IMG SRC path
$imgPATH = $this->getParameter('kernel.project_dir').'/uploads/user_profile_pictures/';
$ext = [".png", ".jpg", ".jpeg", ".gif"];
foreach ($ext as $x) {
$imgPath = $this->getParameter('kernel.project_dir').'/uploads/user_profile_pictures/'.$usertoPic.$x;
if (file_exists($imgPath)) {
return $this->file($imgPath , 'userProfilePicture.png' , ResponseHeaderBag::DISPOSITION_INLINE);
}
}
The image is found by PHP but I get the following broken HTML in the browser; I think this is because it is binary ? how can I convert it to HTML compliant ?
<img id="userIMG" src="�PNG��IHDR���S���S���lЬW���pHYs��.#��.#x�v��OiCCPPhotoshop ICC profile��xڝSgTS�=���BK���KoR RB���&*!J�!��Q�EEȠ�����Q,������������{�kּ������>�����H3Q5��B�������.#�$p��d!s�#��~<<+"���x���M��0���B�\���t�8K��#z�B��#F���&S���`�cb��P-�`" �������{�[�!���="" e�d�h;���v�e�x0�fk�9��-�0iwfh��������="" �0q��)�{�`�##x����f�w<�+��*��x��<�$9e�[-qww.(�i+6aa�#.�y�2�4�����������x����6��_-��"bb���ϫp#���t~��,="" ��;�m��%�h^�u��f�#�����w�p�~<<e���������j�b[a�w}�g�_�w�l�~<�����$�2]�g�����l�ϒ="" �b��g�����"�ib�x*�qq�d���2�"�b�)�%��d��,�="">
Your browser cannot have access to a file that is not in the public (for Symfony 4) folder. That is pretty much the whole point of having a "public" directory.
What you can do is serving the file directly as a binary response given a certain link in your app, like documented here:
https://symfony.com/blog/new-in-symfony-3-2-file-controller-helper
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class ImgController extends Controller
{
/**
* #Route("/get-my-img")
*/
public function getImg()
{
$basePath = $this->getParameter('kernel.root_dir').'/uploads/user_profile_pictures/';
return $this->file($basePath . "img.png");
}
}
// this should work quite simple:
// site/public/css/style.css
<link href="{{ asset('css/style.css') }}" rel="stylesheet" />
// site/upload/favicon.ico
<img src="{{ asset('../upload/favicon.ico') }}" />
$target_dir = '/upload/favicon.ico'; // param in config
$file = $this->getParameter('kernel.project_dir') . $target_dir;
if(is_file($file)) dump('found: ' . $file);
I have seen this answer [
[Determining If a File Exists in Laravel 5 and tried to implement the same method in my project.
I'm using Imageintervention and Laravel 5.4. I have a PropertyController with the following validation code:
//? file upload
if ($request->hasFile('image')) {
$image = $request->file('image');
$filename = time() .'.' .$image->getClientOriginalExtension();
$location = public_path('/imgs/properties/' . $filename);
Image::make($image)->resize(400, 300)->save($location);
$property->image = $filename;
}
//store in the DB
In my show blade i have the following syntax:
<div class="thumbnail">
#if(file_exists(public_path().'../imgs/properties/. $filename'))
<img src="../imgs/properties/{{ $property->image }})" alt="">
#else
<img src="../dist/img/villa.jpg" alt="">
#endif
I put the following code in my Property Model:
public function image()
{
if(file_exists( public_path() . '/imgs/properties/' . $filename)) {
return '/imgs/properties/' . $filename;
} else {
return '../dist/img/villa.jpg';
}
If I register a property with an image I only get the default image and not the newly registered image. I have checked in my properties folder and the image newly registered image is there waiting i fix the problem. Do you have any idea about what went wrong?
Thank you in advance!
I am using laravel Filesystem to store images, the image will be uploaded inside the default storage, example:
/home/user/Projects/mywebapp/storage/app/images/posts/1/e392e17926559e7cc4e7934f.png
I didnt change the config/filesystem.php and here is my controller method to upload an image,
public function storeImage( Request $request ) {
$image = $request->file( 'image' )->store( 'images/posts/'.Auth::user()->id );
echo Storage::url( $image ); // <- print the url of the uploaded image
}
This would print the image url like this,
http://localhost:8000/storage/images/posts/1/e392e17c6a8d7926559e8e7cc4e7934f.png
But the image file is not accessable from the browser!
I dont want to use php to dynamically fetch the images, i just wanted to make them publicly accessable over http. How to display the image?
you just have to make a change in config\filesystems.php form
'default' => local,
to 'default' => public,
then in console run php artisan storage:link
then try the above code and it will work
For me it worked when I added "../" to the url of the file:
#foreach($arquivos as $i)
<li class="list-group-item"> <img src="{{ asset('img/pdf.png') }}" /> {{ $i -> nome }} </li>
#endforeach
And I am saving the file like this:
$ext = $request->arquivo->extension();
$path = $request->arquivo->storeAs('/relatorios', $nameoffile. "." . $ext);
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;
}