load image to fabric canvas background - javascript

hi im trying to upload an image and put it as canvas background. code snippet:
function handleMenuImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.src = event.target.result;
canvas.setWidth(img.width);
canvas.setHeight(img.height);
canvas.setBackgroundImage(img.src, canvas.renderAll.bind(canvas));
//set the page background
menuPages[currentPage].pageBackground.src = img.src;
canvas.backgroundImageStretch = false;
}
reader.readAsDataURL(e.target.files[0]);
}
the problem is that the canvas not showing the background. i can see the canvas background src in chrome devtools. the background is actually have been set but somehow its not displayed.

That seems strangely confusing. If you want a background image on an HTMLCanvasElement, why not just set the background image via CSS?
#myCanvas {
background-image: url(http://placekitten.com/100/100);
}
Or set the CSS via JavaScript:
canvas.style.backgroundImage = 'url(http://placekitten.com/100/100)';

Try the following code:
var raw_reader = new FileReader();
raw_reader.onload = function (event){
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.src = event.target.result;
canvas.setWidth(img.width);
canvas.setHeight(img.height);
canvas.setBackgroundImage(img.src, canvas.renderAll.bind(canvas));
//set the page background
menuPages[currentPage].pageBackground.src = img.src;
canvas.backgroundImageStretch = false;
}
reader.readAsDataURL(e.target.files[0]);
}
raw_reader.readAsBinaryString(e.target.files[0]);

Related

How to make input type file in canvas to upload image

I need to add button on canvas to upload image. I tried this
Try1)
var input = document.createElement("INPUT");
input.setAttribute("type", "file");
document.getElementById('canvas').appendChild(input);
Try2) // using createjs
let uploadbtn = new createjs.Container()
stage.addChild(uploadbtn)
var rptxt = new window.createjs.Text("upload Photo", "12px Arial", "#fff");
rptxt.x=rptxt.y=8;
uploadbtn.addChild(rptxt)
uploadbtn.addEventListener('click',()=>{
var reader = new FileReader();
reader.onload = function(event){
var img = new Image();
img.onload = function(e){
let b = new createjs.Bitmap(e.target)
stage.addChild(b)
}
img.src = event.target.result;
}
})
Both option did not work for me.
In canvas it's not possible to create DOM elements like DIV, Buttons, UL, LI Span, P etc... so alternatively we need to create in normal html and adjust it with absolute position on top of canvas.

Can't draw imported image through input file

I am trying to load an image with an html input type="file" and load it to an with javascript without success.
Here is my code so far:
HTML:
<canvas class="imported" id="imported"></canvas>
<button class="import_button" id="import_button">Import a picture</button>
<input type="file" id="imgLoader"/>
JAVASCRIPT:
document.getElementById('import_button').onclick = function() {
document.getElementById('imgLoader').click();
};
document.getElementById('imgLoader').addEventListener('change', importPicture, false);
function importPicture()
{
alert("HERE");
var canvas = document.querySelector('#imported');
var context = canvas.getContext("2d");
var fileinput = document.getElementById('imgLoader');
var img = new Image();
var file = document.getElementById('imgLoader').files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
reader.onload = function(evt)
{
alert("THERE");
if( evt.target.readyState == FileReader.DONE)
{
alert("AGAIN");
img.src = evt.target.result;
context.drawImage(img, 200, 200);
}
}
}
The alerts are all fired up, no errors or message in the console..
How can I load it and display it? Thank you!
The logic (of your original code, not the edited version) is a bit baffling:
document.getElementById('imgLoader').addEventListener('change', importPicture, false);
adds a change event to the file input. That's fine. But then within the "importPicture" function, which runs when the file input changes, you add another change event listener (via fileinput.onchange) ...why are you doing that? I can't see how it makes sense. It means you have to change the file again before the code in there runs. And it also means that every time you change the file it adds more and more listeners, until you have lots of functions firing at once.
The other problem is that you're not waiting for the data to be loaded into the Image object before you try to draw the image on the canvas. You also need to set the dimensions of the canvas itself, and not be prescriptive about the dimensions of the image (because the user could upload anything, of any size).
Here's a working demo:
document.getElementById('import_button').onclick = function() {
document.getElementById('imgLoader').click();
};
var fileinput = document.getElementById('imgLoader').addEventListener('change', importPicture, false);
function importPicture() {
var canvas = document.querySelector('#imported');
var context = canvas.getContext("2d");
var img = new Image();
var file = this.files[0];
var reader = new FileReader();
reader.onload = function(evt) {
img.onload = function() {
canvas.width = img.width;
canvas.height = img.height;
context.drawImage(img, 0, 0);
}
img.src = evt.target.result;
}
reader.readAsDataURL(file);
}
<canvas class="imported" id="imported"></canvas>
<button class="import_button" id="import_button">Import a picture</button>
<input type="file" id="imgLoader" />
Credit to this answer for the final bits.

FileReader dragging image from browser window

I have a div where users can drag and drop an image and then, using FileReader, I get the base64 of the image. Works fine.
dropper.ondrop = function (e) {
e.preventDefault();
var file = e.dataTransfer.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
};
My issue is if I have a browser window open and drag and drop an image from the browser I get the error:
Failed to execute 'readAsDataURL' on 'FileReader':
parameter 1 is not of type 'Blob'.
Now, is there any turnaround to get the base64 of an image dragged from the browser window?
Ultimately, is there is a way to get the image URL and then the actual base64 with a server side curl request?
Any idea?
You can use e.dataTransfer.getData('url') to tell whether there's a URL available. Like this:
var url = e.dataTransfer.getData('url');
if(url){
console.log('Url');
console.log(url);
}else{
console.log('File');
var file = e.dataTransfer.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
}
Then, having the URL, you can load an img element and use draw it on a canvas to grab the base64 representation. Like this:
var img = document.createElement('img');
img.crossOrigin = 'anonymous';
img.onload = function(){
var canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
var context = canvas.getContext('2d');
context.drawImage(this, 0, 0);
console.log(canvas.toDataURL());
};
img.src = url;
This would be the "final" product:
var dropper = document.querySelector('div');
dropper.ondragover = function(e) {
e.preventDefault();
}
dropper.ondrop = function (e) {
e.preventDefault();
var url = e.dataTransfer.getData('url');
if(url){
console.log('Url');
console.log(url);
var img = document.createElement('img');
img.crossOrigin = 'anonymous';
img.onload = function(){
var canvas = document.createElement('canvas');
canvas.width = this.width;
canvas.height = this.height;
var context = canvas.getContext('2d');
context.drawImage(this, 0, 0);
console.log(canvas.toDataURL());
};
img.src = url;
}else{
console.log('File');
var file = e.dataTransfer.files[0];
var reader = new FileReader();
reader.readAsDataURL(file);
}
};
div{
border:1px solid red;
height:240px;
width:100%;
}
<div>Drop here</div>
Also available here: https://jsfiddle.net/8u6Lprrb/1/
The first parameter comes through with the "http://" or "https://" protocol instead of the expected "file://" protocol. and thats why you cant read it with the HTML5 FILE API, so you may want to download and save the file first before trying to read the contents.
on the other hand, you can update an img tag's src attribute with the retrieved url and skip the readDataAsUrl() portion to hotlink the image.

Adding Image to a PDF using jspdf makes the image black

When i try to add the image in the URL to a PDF file the image comes completley black.
But when I click the download pdf button again the image gets added to the PDF.Only
when I do it the first time, the image comes as black.
function getBase64Image(url) {
alert(url);
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var img = new Image();
img.src = url;
img.style.height ="181px";
img.style.width ="183px";
//img.crossOrigin ="Anonymous";
context.drawImage(img,0,0);
var dataURL = canvas.toDataURL("image/jpeg");
alert(dataURL);
document.body.appendChild(img);
var doc = new jsPDF('landscape');
doc.addImage(img,'JPEG',0,0,50,50);
doc.save('Saved.pdf');
}
getBase64Image("http://localhost:64931/jspdf/download.png");
What happens when you change your code like this:
A changed JPEG to PNG, that worked for me.
function getBase64Image(url) {
alert(url);
var canvas = document.getElementById('myCanvas');
var context = canvas.getContext('2d');
var img = new Image();
img.src = url;
img.style.height ="181px";
img.style.width ="183px";
//img.crossOrigin ="Anonymous";
context.drawImage(img,0,0);
var dataURL = canvas.toDataURL("image/png");
alert(dataURL);
document.body.appendChild(img);
var doc = new jsPDF('landscape');
doc.addImage(img,'PNG',0,0,50,50);
doc.save('Saved.pdf');
}
getBase64Image("http://localhost:64931/jspdf/download.png");
I was facing the same issue yesterday, and writing this answer incase someone finds it useful
What I was trying to achieve?
I was converting the doc (pdf) into a blob and then opening it in a print dialogue, but the image was black.
var blob = new Blob([doc.output()], { type: "application/pdf" });
This is how I was trying to convert it into a blob.
but this resulted in a black image
Solution
jsPDF allows us to add arguments in the output function.
[](jsPDF output api)
adding type as bloburl works for me, as i was opening a print dialogue using the blob url
let iframe = document.createElement("iframe"); //load content in an iframe to print later
document.body.appendChild(iframe);
//* print dialogue
iframe.style.display = "none";
iframe.src = blobURL;
console.log(blobURL) // same blobURL that was received from jsPDF
iframe.onload = function () {
setTimeout(function () {
iframe.focus();
iframe.contentWindow.print(); // opens a print dialogue box
}, 1);
};

Add image from user computer to canvas

i'm working on a web app that allow users to create dynamic slideshow. Currently i've got an issue regardless how to add image from the computer's user to the canvas.
I'm using a input button to get the file from the computer and it appeal a function who will add the image to the canvas.
So far i've tried different ways to add the image to the canvas as well as this one : Dynamically add image to canvas
But the code showing here doesnt work in my case, because it just draw the image into the canvas but it wont allow it to be draggable and resizable just like the Kitchensink.js demo from Fabricsjs.
I've also try to convert the image into Base64 and use the LoadJSON to convert it back but i encountered this error :
Uncaught TypeError: Cannot read property 'length' of undefined fabric.js:2089
enlivenObjects fabric.js:2089
fabric.util.object.extend._enlivenObjects fabric.js:9025
fabric.util.object.extend.loadFromJSON fabric.js:8953
sub
Sub's refering to the function i've called to add the image.
I've also try this code :
document.getElementById('imgLoader').onchange = function handleImage(e){
var reader = new FileReader();
reader.onload = function(event){
var img = new fabric.Image();
img.onload = function(){
img.set({
left : 250,
top : 250,
angle : 20,
padding: 10,
cornersize: 10
});
image.scale(getRandomNum(0.1, 0.25)).setCoords();
canvas.add(image);
}
img.src = event.target.result;
}
reader.readAsDataURL(e.target.files[0]);
}
Which catch these errors :
Uncaught TypeError: Cannot read property 'width' of undefined fabric.js:14358
fabric.Image.fabric.util.createClass._setWidthHeight fabric.js:14358
fabric.Image.fabric.util.createClass._initConfig fabric.js:14334
fabric.Image.fabric.util.createClass.setElement fabric.js:14127
fabric.Image.fabric.util.createClass._initElement fabric.js:14322
fabric.Image.fabric.util.createClass.initialize fabric.js:14097
(anonymous function) fabric.js:2679
klass fabric.js:2728
reader.onload diapo.js:746
I've cleary run out of ideas and only achieved to draw the image but not adding it to the canvas.
All in one i'd like to add an image to my Fabricjs canvas with the same attributes regardless the draggable as the Kitchensink demo.
Thanks in advance for your help :)
There is one basic mistake in your code, you are trying to add the image data to the src attribute of the fabric.Image object.
What you need to do, is to create an Image object with your result, and pass it to the fabric.Image object, like this:
var imgObj = new Image();
imgObj.src = event.target.result;
imgObj.onload = function () {
var image = new fabric.Image(imgObj);
}
I made a working example here:
http://jsfiddle.net/jaibuu/Vp6wa/
Upload image in canvas from computer by Fabric js.
var canvas = new fabric.Canvas('canvas');
document.getElementById('file').addEventListener("change", function (e) {
var file = e.target.files[0];
var reader = new FileReader();
reader.onload = function (f) {
var data = f.target.result;
fabric.Image.fromURL(data, function (img) {
var oImg = img.set({left: 0, top: 0, angle: 00,width:100, height:100}).scale(0.9);
canvas.add(oImg).renderAll();
var a = canvas.setActiveObject(oImg);
var dataURL = canvas.toDataURL({format: 'png', quality: 0.8});
});
};
reader.readAsDataURL(file);
});
canvas{
border: 1px solid black;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://rawgit.com/kangax/fabric.js/master/dist/fabric.min.js"></script>
<input type="file" id="file"><br />
<canvas id="canvas" width="450" height="450"></canvas>

Categories