Intervention Image broken in Vue - laravel

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" />.

Related

laravel passing a variable to js file from a controller

I have a js file located in assets folder (not View). can i pass a varible from a controller?
In view file:
The Js is called like this
<canvas id="chart1" class="chart-canvas"></canvas>
</div>
It is not possible (in my point of view) to put a variable to external JS file. You can use data-... attributes and get values from html elements.
For example you can pass your PHP variable as a json encoded string variable in your controller.
$data['chart_info'] = json_encode($chart_info);
return view('your_view', $data);
Then put it in data-info like this.
<canvas id="chart1" class="chart-canvas" data-info="{{ $chart_info }}"></canvas>
And finally in JS, you can get the variable and decode (parse) it as following.
let canvas = document.getElementById('chart1');
let info = JSON.parse(canvas.dataset.id);
console.log(info);
You can put that part of the Javascript in the view and send the variable to the same view. For example, add a section in view:
#section('footer')
<script type="text/javascript">
</script>
#endsection
Do not forget that you should add #yield('footer') to the end of your layout view.
I don't like to mix javascript and PHP/Blade, it might be hard to read the code in the future... You could use a different approach, loading the chart with a async ajax request.
You will have to create a end-point that returns the data you need for your chart:
Your router:
Route::get('/chart/get-data', [ ControllerName::class, 'getChartData' ]);
Your controller method:
public function getChartData() {
$chartData = [];
// Your logic goes here
return $chardData;
}
In your javascript (using jquery) file there will be something like that:
function loadChartData() {
$.ajax({
'url': '/chart/get-data',
'method': 'GET'
})
.done((data) => {
// Load your chart here!!!
})
.fail(() => {
console.log("Could not load chart data");
});
}
Hope I helped ;)

How to use Vue method as image source?

in Vue I am trying to use the result from a method as the source for an image:
HTML:
<img :src="getEnergyIcon(type)">
JS:
data() {
return {
energyTypeMap: new Map([
['colorless','#/assets/images/energy-icons/20px-Colorless-attack.png'],
['darkness','#/assets/images/energy-icons/20px-Darkness-attack.png'],
['dragon','#/assets/images/energy-icons/20px-Dragon-attack.png'],
['fairy','#/assets/images/energy-icons/20px-Fairy-attack.png'],
['fighting','#/assets/images/energy-icons/20px-Fighting-attack.png'],
['fire','#/assets/images/energy-icons/20px-Fire-attack.png'],
['grass','#/assets/images/energy-icons/20px-Grass-attack.png'],
['lightning','#/assets/images/energy-icons/20px-Lightning-attack.png'],
['metal','#/assets/images/energy-icons/20px-Metal-attack.png'],
['psychic','#/assets/images/energy-icons/20px-Psychic-attack.png'],
['water','#/assets/images/energy-icons/20px-Water-attack.png'],
])
}
},
And:
methods: {
getEnergyIcon(type){
return this.energyTypeMap.get(type.toLowerCase());
}
},
The method returns the correct path, but the image doesn't use that path as the source:
I want the result to be the same as the hardcoded result, but I want to achieve this by using the method, because I am going to use dynamic data that gives me one of the 11 types, I cannot use hardcoded paths.
I have been Googling around to find a solution but I can't find a solution that uses a direct method as a source for the image. How do I do this?
Thanks in advance.
Found this topic:
How to reference static assets within vue javascript
That mentioned the following:
In a Vue regular setup, /assets is not served.
The images become src="..." strings, instead.
And required me to use:
require();
Which I did like this:
data() {
return {
card: {},
energyTypeMap: new Map([
['colorless',require('#/assets/images/energy-icons/20px-Colorless-attack.png')],
['darkness',require('#/assets/images/energy-icons/20px-Darkness-attack.png')],
['dragon',require('#/assets/images/energy-icons/20px-Dragon-attack.png')],
['fairy',require('#/assets/images/energy-icons/20px-Fairy-attack.png')],
['fighting',require('#/assets/images/energy-icons/20px-Fighting-attack.png')],
['fire',require('#/assets/images/energy-icons/20px-Fire-attack.png')],
['grass',require('#/assets/images/energy-icons/20px-Grass-attack.png')],
['lightning',require('#/assets/images/energy-icons/20px-Lightning-attack.png')],
['metal',require('#/assets/images/energy-icons/20px-Metal-attack.png')],
['psychic',require('#/assets/images/energy-icons/20px-Psychic-attack.png')],
['water',require('#/assets/images/energy-icons/20px-Water-attack.png')],
])
}
},
It has solved my problem.

check in blade view if image is loaded or 404

Is there a way to check in a blade view if an image is really there or not?
I need to show results from a search box.
The results are many boxes with infos and a picture for each box.
The point is in my DB I store links to images that are on remote servers and also name of images that are stored locally.
So what I am doing is check if the file exists locally and if so use it and if not look on the remote server (if the picture data is not NULL it's either there or in a remote server).
I was trying to check if file exists using curl and it works but for big collections it takes too much time to finally spit the data to the view (every link has to be checked).
So what I want to do, if possible, is check directly in the blade view if the picture is not broken (404) and if so replace with an "image-not-found.png" I store locally. How can I do that?
I usually handle this with JavaScript using the img tag's onerror event. Typically I add a few more bells and whistles to the solution but this is it in a nutshell.
Plan JavaScript
function loadNextImage(id,uri){
document.getElementById(id).src = uri;
}
Plain HTML
<img src="http://local/image.jpg"
onerror="loadNextImage('image1', 'http://remote/imae.jpg'));"
id='image1' />
VueJS and Webpack
<template>
<img :src="local_url" #error="imgOnError()" ref="image"/>
</template>
<script>
export default{
name: 'Thumbnail',
props: {
local_url: String,
remote_url: String
},
methods: {
imgOnError: function (e) {
this.$refs.image.src = this.remote_url
}
}
}
</script>
You can use the func "file_get_contents" inside a try-catch block. I know i not the best way, but i could work for you.
Tray this (no the best way):
<?php
try{
$img = 'myproject.dev/image.jpg';
$test_img = file_get_contents($img);
echo "<img src='{$img}'>";
}catch(Exception $e){
echo "<img src='img/no-img.jpg'>";
}
?>

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

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.

problem rendering image in browser FileContentResult

I want to show an image from database
I have an action
public FileContentResult GetImage(string param)
{
type obj = _someRepository.GetType(param);
if (obj!= null && obj.Image!= null)
{
return File(obj.Image.ToArray(), obj.Image.MimeType);
}
return "some default image";
}
in the view I have
< img src="<%:Url.Action("GetImage","ControllerName",new { param= somevalue })%>" alt="some text"
width="100px" height="100px" />
I also have
(Html.BeginForm("actionname", "controllername", FormMethod.Post, new { enctype = "multipart/form-data" })
set.
The image data is fetched from the database But I can't see the image in the browser,
is there something that I am missing?
Here are the steps I would perform in order to isolate the problem. Start with a simple controller action which returns some hardcoded image somewhere from your harddrive:
public ActionResult GetImage(string param)
{
byte[] image = File.ReadAllBytes(#"c:\work\foo.png");
return File(image, "image/png");
}
Now navigate directly to /ControllerName/GetImage in your browser and you should see the image.
The next step is to fetch the image from the database and probably store it on your harddisk to ensure that it is a valid image:
type obj = _someRepository.GetType(param);
File.WriteAllBytes(#"c:\work\foo.png", obj.Image.ToArray());
Now checkout the generated file and see if it is valid. The last step is to ensure that the url generated in the <img> tag is the same as the one you used to test directly. Then look at FireBug's Net tab to see if the browser correctly requests the image and what does the server return.
Most probably the issue is that the byte array returned from the database is not valid image or it is empty.
As far as the form you have shown in your question, this is for uploading files, it has nothing to do with serving dynamic images from a controller action, so I don't see what relation it might have to your question.

Resources