Show an image in a blade file after using Intervention Image (Laravel) - image

I want to show an image in a blade template that contains already some HTML code after doing some modifications (resize, insert...) to this image using the Intervention Image library.
Example :
public function image(){
return $img = Image::make('images/test.jpg')
->resize(800, 500)
->insert('some_url', 'bottom-right', 10, 10)
->text('foo', 100, 100, function($font) {
$font->file('fonts/font.ttf');
$font->size(100);
$font->color('#fdf6e3');})
->response();
}
This method is called using this route :
Route::get('/image', 'MyController#image');
The result is perfect :)
but I want to show this image in a blade template that contains already HTML code, and not just return the image using the route.
Thanks in advance.

Try just setting returned like this <img src="$img"> in your blade.

Related

Intervention Image broken in Vue

I'm trying to create an image on the fly without saving and sending to the Vue but I can't get to display.
in Laravel
$img = Image::make('image-path')->resize(400, 400);
$img->text('name', 205, 138, function($font) {
$font->file('fonts/BostonHeavy.woff');
$font->size(42);
$font->color('#ffffff');
$font->align('center');
$font->valign('top');
});
return $img->response('jpg');
in Vue
data () {
return {
image: null
}
},
methods: {
async fetchData (param) {
this.image = await this.$axios.$get(`image`)
}
}
in template
{{image}}
or
<img :src="image" />
always displays broken, though testing on Postman it works
Currently, you are putting a bunch of binary data into your img's src attribute, which does not work.
You need to convert the image to a data URL as described here How can I convert image binary from API call to data URI in Javascript?
If your endpoint does not need authentication (or any other special headers or payloads) you could also directly put the link to the image-generating endpoint directly into your img's src attribute. E.g. if your image is generated at /api/image then just simply put <img src="/api/image" />.

Laravel: Display image from public storage

I am saving an uploaded image like this:
$profile_picture = $request->file('profile_picture');
$user->profile_picture = $profile_picture->getClientOriginalName();
Storage::disk('public')->put( $user->profile_picture, $request->file('profile_picture') );
and then I am trying to display that image in HTML with:
<img class="img-fluid" src="{{ asset('storage/'. Auth::user()->profile_picture) }}">
the image is being saved in storage/app/public, but the image is not showing in html, how do i go about this?
thank you
You may use response method on a Laravel filesystem
return Storage::disk('public')->response($user->profile_picture);
N.B: In order to do that, you need a Laravel route. The above code should be located in a controller method

Spatie media library getMedia() not returning all images

I am receiving multiple images in base64 from rich text editor. My idea was to upload all the images and replace base64 img src in article content with newly created image path. I am using spatie media library and Laravel.
foreach ($data['images'] as $image) {
$article->addMediaFromBase64($image)->toMediaCollection('article-images');
$mediaItems = $article->getMedia('article-images');
$article->content = str_replace($image, $mediaItems[count($mediaItems) - 1]->getFullUrl(), $article->content);
$article->save();
}
The problem I have is that $article->getMedia('article-images') always returns only the first created image and the count is always one. So what ends up happening is no matter how many images I upload it will replace all their src tags with the url of the first image.
This is the final solution I went with. The relationship was probably cached after the first image upload and that's probably why I was always getting the first image. After loading media relation on the model, I was able to retrieve all images in the collection properly.
foreach ($data['images'] as $image) {
$article->addMediaFromBase64($image)->toMediaCollection('article-images');
$mediaItems = $article->load('media')->getMedia('article-images');
$article->content = str_replace($image, $mediaItems[count($mediaItems) - 1]->getFullUrl(), $article->content);
}

Laravel SnappyPDF image attachment

Im currently using barryvdh/laravel-snappy to convert my data to pdf format.
The code i'm using is :
public function generate_pdf($id){
$rfq = RFQ::find($id);
$data = array(
'rfq' => $rfq,
);
//return view('rfq.pdf')->with('rfq', $rfq);
$pdf = PDF::loadView('rfq.pdf',$data)->setPaper('a4')->setOption('margin-bottom', 0);
return $pdf->download($rfq->rfq_no.'-'.date_timestamp_get(date_create()).'.pdf');
}
And then, I have to add an image to the pdf file. So i have to add this line to the pdf.blade.php file.
<img src="{{ asset('img/logo.png') }}">
But then, the image isn't showing properly.
It's visible, but it's OPACITY is very low, around 0.2.
But when viewing the actual image file, and the one in the actual html template, everything's good.
I tried <img src="data:image/png;base64,{{ base64_encode(#file_get_contents(asset('img/logo.png'))) }}">
but still, it's the same.

Including SVG contents in Laravel 5 Blade template

What is the best way to include the contents of an SVG file (located in the assets folder) in a Laravel 5 blade template?
I don't want to use image/object/embed tags, this should be an inline SVG for reasons of speed.
I know I could use <?php file_get_contents("file.svg") ?> but is there a better way specific to Laravel/Blade?
Edit: to clarify, the method should work with all SVG files, including the one below.
<?xml version="1.0" encoding="UTF-8"?>
<svg xmlns="http://www.w3.org/2000/svg">
<path stroke="red" fill="#00f" d="M10 10h100v100H10z"/>
</svg>
Similar to the accepted answer but a bit cleaner (imo).
Use the laravel directive to extend blade, like so (in your App Service Provider, as outlined here):
\Blade::directive('svg', function($arguments) {
// Funky madness to accept multiple arguments into the directive
list($path, $class) = array_pad(explode(',', trim($arguments, "() ")), 2, '');
$path = trim($path, "' ");
$class = trim($class, "' ");
// Create the dom document as per the other answers
$svg = new \DOMDocument();
$svg->load(public_path($path));
$svg->documentElement->setAttribute("class", $class);
$output = $svg->saveXML($svg->documentElement);
return $output;
});
Then use it in your blade like so:
<div class="Login__image Login__cloud">
#svg('cloud.svg', 'Cloud')
</div>
This works, that's the simplest way I could think about :
{!! file_get_contents('images/icon.svg') !!}
Why not place the svg into a blade template?
resources/views/icons/dashboard.blade.php
then add in your views using blade syntax?
#include('icons.dashboard')
View Composer Method
I ended up using a view composer in a service provider.
In the service provider's boot() method:
// Wildcard view composer
view()->composer('*', function($view) {
// Instantiate new DOMDocument object
$svg = new DOMDocument();
// Load SVG file from public folder
$svg->load(public_path('images/logo.svg'));
// Add CSS class (you can omit this line)
$svg->documentElement->setAttribute("class", "logo");
// Get XML without version element
$logo = $svg->saveXML($svg->documentElement);
// Attach data to view
$view->with('logo', $logo);
});
And in my view:
<!-- Echo unescaped SVG content -->
{!! $logo !!}
I am using DOMDocument as it allows me to remove the XML version element which should not be in the HTML.
The CSS class is not essential but saves me wrapping the logo with another HTML element for styling.
If you only need the logo in a specific Blade partial such as header you could write
view()->composer('header', function($view) {});
http://laravel.com/docs/5.0/views#view-composers
https://laracasts.com/series/laravel-5-fundamentals/episodes/25
Blade Partial Method
This method is not best practice since this sort of code should not really be in a view. However it is very simple and much better than adding PHP code in every single view.
Make a new partial (lets say logo.blade.php) with the following code:
<?php
// Instantiate new DOMDocument object
$svg = new DOMDocument();
// Load SVG file from public folder
$svg->load(public_path('images/logo.svg'));
// Add CSS class (you can omit this line)
$svg->documentElement->setAttribute("class", "logo");
// Echo XML without version element
echo $svg->saveXML($svg->documentElement);
?>
You can now use the SVG image in a blade template by including the partial like so:
#include('logo')

Resources