How to fill canvas and add text - javascript

I want to fill my canvas with a image (base64-string) and than add a text into the canvas.
Initial idea (javascript browser application): I want to set the base64-string txtb64 (Image) as background image of the canvas and than add the text over it.
downloadtext: function() {
var sign = this.getView().byId("SigId");
var txtb64 = signpad.getSignAsJpeg();
var canvas = document.createElement("canvas");
var ctx = canvas.getContext('2d');
var image = new Image();
image.src = txtb64;
image.addEventListener("load", function(event) {
console.log("Ready!");
});
ctx.drawImage(image, 0, 0);
ctx.fillText('My random text', 0, 0);
var dataURL = canvas.toDataURL("image/jpeg");
var image = new Image();
var element = document.createElement('a');
image.src = dataURL;
element.setAttribute('href', image.src);
element.setAttribute('download', 'image');
element.style.display = 'none';
element.click();
},
The problem is I always get a black rectangle as output.
What is wrong with my code, because i can see no error.

It looks like you should put the code needed to download the new image inside the "load" event handler of the image you create. This is needed because the load event could trigger after the code beneath it runs, resulting in an empty image being put onto the canvas.
Also you declare var image = new Image(); twice, which could also be causing issues. Calling one image1 and the other image2 will prevent that.
WARNING Running this snippet triggers a download request.
var data = "data:image/png;base64,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";
var can = document.getElementById('can');
var ctx = can.getContext('2d');
var img = new Image();
img.src = data;
img.addEventListener('load', e =>
{
ctx.drawImage(img, 0, 0);
ctx.fillText('My random text', 100, 100);
var dataURL = can.toDataURL("image/jpeg");
var image = new Image();
var element = document.createElement('a');
image.src = dataURL;
element.setAttribute('href', image.src);
element.setAttribute('download', 'image');
document.body.appendChild(element);
element.click();
});
<canvas width="300" height="300" id="can"></canvas>

Related

Image src local file in popup window open with Chrome Extension

I've made a Chrome Extension that:
Takes a screenshot of a website, opens anew window, cuts the image using canvas, and downloads the image. Now I want to display the image so I create an image and set its path to file:///C:/Users/myuser/Downloads/myfile.png.
But the image doesn't show up. I tried removing the "file" or setting a timeout but nothing works, however when I click the image link in the dev console it takes me to the picture and it works.
Here's the code from ´background.js´:
chrome.browserAction.onClicked.addListener(function(tab) {
chrome.tabs.captureVisibleTab(null, {}, function(image){
var x = window.open();
var cv = x.document.createElement('canvas');
x.document.body.appendChild(cv);
var canvas = x.document.querySelector('canvas');
canvas.width = 928
canvas.height = 490;
var img = new Image();
var code = new Date().getTime();
img.onload = function(){
ctx.drawImage(this, 315, 138, 928, 490, 0, 0, 928, 490);
var toCopy = canvas.toDataURL("image/png");
var link = x.document.createElement('a');
link.download = code + '.png';
link.href = toCopy;
link.click();
setTimeout(function(){
var el = new Image();
el.src = 'file:///C:/Users/myuser/Downloads/'+code+'.png';
x.document.body.appendChild(el);
x.console.log(x.location);
}, 2000);
canvas.parentElement.removeChild(canvas);
}
img.src = image;
var ctx = canvas.getContext('2d');
});
});

Unable to load an Image into Canvas and get base64 encoding for that image

I am trying to generate a PDF from HTML using jspdf plugin. I am stuck with loading Images into PDF. There is a function addImage() in plugin which takes base64 encoding of an image, but converting an image to base64 is not working.
I have used below two ways
//Create canvas, draw image in context and get the data url
imgToDataURL = function (img, outputFormat){
var canvas = document.createElement('canvas');
canvas.width = 20;
canvas.height = 20;
var c = canvas.getContext('2d');
c.height = img.height;
c.width=img.width;
c.drawImage(img, 0, 0);
c.save();
var dataurl = canvas.toDataURL(outputFormat);
return dataurl;
}
var img = new Image();
img.crossOrigin = 'Anonymous';
img.src = "image path"
img.height= 60;
img.width=60;
var dataURL = this.imgToDataURL(img,"image/jpeg");
renderer.pdf.addImage(dataURL, 'png',x+padding,y + this.internal.getLineHeight(),imageWidth,imageHeight);
This is printing wrong dataURL I am getting a white image. If I hard code the base64 code i.e return a hardcoded dataURL then addImage works fine. So the issue is with canvas.toDataURL which is giving me wrong output
this is the 2nd way
convertImgToBase64URL = function (url, callback, outputFormat){
var img = new Image();
img.crossOrigin = 'Anonymous';
img.onload = function(){
var canvas = document.createElement('CANVAS'),
ctx = canvas.getContext('2d'), dataURL;
canvas.height = this.height;
canvas.width = this.width;
ctx.drawImage(this, 0, 0);
dataURL = canvas.toDataURL(outputFormat);
callback(dataURL);
canvas = null;
};
img.src = url;
}
this.convertImgToBase64URL("Image Path",function(base64){
renderer.pdf.addImage(base64, 'PNG', 20, 20,48,48);
})
I have run this inside a javascript and the onload function is not even running I am not sure what is my mistake is.
Please suggest me what mistake I am doing in either way
In the first you missed assigning an onload function to your image. For that reason, the moment you try to create the dataURL, the image might not be loaded yet, ergo, the blank image. You could try changing the last few lines to this:
...
img.width=60;
img.onload = function () {
var dataURL = this.imgToDataURL(img,"image/jpeg");
renderer.pdf.addImage(dataURL, 'png',x+padding,y + this.internal.getLineHeight(),imageWidth,imageHeight);
}
img.src = "image path";
As for the second one, there seems to be a problem with the convertImgToBase64URL() which accepts 3 parameters, but you are passing 2. In you example, outputFormat parameter is undefined.

Resize the canvas output image to a specific size (width/height)

I have a big canvas (5000x5000) and I want to take a picture of it and create a thumbnail on client side. I can capture the image using canvas.toDataURL but how do i re-size it? Do i have to create an new $("<canvas></canvas>") element and then put that image inside and run the canvas2.toDataURL(); Can anyone help me with this? I can't get my head around it how to do it.
var canvas = document.getElementById("main");
var ctx = canvas.getContext("2d");
var tumbnail64 = null;
var image = new Image();
image.src = canvas.toDataURL();
image.onload = function() {
$c2 = $("<canvas></canvas>");
$c2[0].width=100;
$c2[0].height=100;
$c2[0].getContext("2d");
$c2[0].drawImage(image, 0, 0,100,100);
tumbnail64 = $c2[0].toDataURL();
};
Something like this should work, given you don't have security restrictions on the original canvas element:
var resizedCanvas = document.createElement("canvas");
var resizedContext = resizedCanvas.getContext("2d");
resizedCanvas.height = "100";
resizedCanvas.width = "200";
var canvas = document.getElementById("original-canvas");
resizedContext.drawImage(canvas, 0, 0, 200, 100);
var myResizedData = resizedCanvas.toDataURL();

Displaying one canvas to another

I have a problem displaying one canvas to another. I do everything according to this solution
<script>
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
}
img.src = 'icon.jpg';
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
destin_ctx.drawImage(source, 0, 0);
</script>
Well, first canvas element displays picture correctly, but whatever I do, the second canvas does not want to display a picture.
<script>
function init()
{
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
destin_ctx.drawImage(source, 0, 0);
}
img.src = 'arun.jpg';
}
</script>
</head>
<body onload="init();">
<canvas id="hiddenCanvas" />
<canvas id="visibleCanvas" />
Your code is not working because you are trying to access canvas element before it is loaded to dom
The way you've currently structured the code, img.onload is executed after the destin_ctx.drawImage line. That means that your program flow currently looks something like this:
Image is told to start loading
Destination canvas is drawn using (currently blank) source canvas
Image finishes loading
Image's onload executes, causing the source canvas to be drawn to. The destination canvas is NOT updated, because the destin_ctx.drawImage operation is a one-time copy.
What you need to do is move the destin_ctw.drawImage call to a place in the execution flow where you know the source canvas will definitely contain the appropriate contents. In this simple case, moving it to inside the image's onload would work.
Here's a full (but simplified) HTML file that works for me in Chromium, with a changed image url:
<script>
function load() {
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
destin_ctx.drawImage(source, 0, 0);
}
img.src = 'ship360_32.png';
}
</script>
<body onload="load()">
<canvas id="hiddenCanvas"></canvas>
<canvas id="visibleCanvas"></canvas>
</body>
You are trying to draw the image from source before the image is loaded and the source even have the image.
Move the last draw operation inside the onload handler. Also remember to set the size for destination canvas:
var source = document.getElementById('hiddenCanvas');
var source_ctx = source.getContext('2d');
var destination = document.getElementById('visibleCanvas');
var destin_ctx = destination.getContext('2d');
var img = new Image();
img.onload = function(){
source.width = img.width;
source.height = img.height;
source_ctx.drawImage(img, 0, 0, img.width, img.height);
destination.width = source.width;
destination.height = source.height;
destin_ctx.drawImage(source, 0, 0);
}
img.src = 'icon.jpg';

Javascript - How to wait for image to load? Cant get img.load to work?

In my javascript i draw onto a canvas, after that i whant the canvas to be converted to a png and shown in a div with the folowing code:
var dataURL = document.getElementById('myCanvas').toDataURL("image/png");
var imgObj = new Image();
imgObj.src = dataURL;
imgObj.onload = function() {document.getElementById('myImg').appendChild(imgObj); };
When i call this directly after drawing the canvas i get a completly blank image in "myImg" but if i call exactly the same code with the click on a link it gets drawn properly:
<a id="viewImgLnk" href="javascript:void()" onclick=" return convertCanvasToImage();">View Image</a>
<script>
function convertCanvasToImage(){
var dataURL = document.getElementById('myCanvas').toDataURL("image/png");
var imgObj = new Image();
imgObj.src = dataURL;
imgObj.onload = function() {document.getElementById('myImg').appendChild(imgObj); };
}
</script>
How can i get the image loaded directly without the link?
I got the code working with the help of allergic!
setTimeout(function() {
var dataURL = document.getElementById('myCanvas').toDataURL("image/png");
var imgObj = new Image();
imgObj.src = dataURL;
imgObj.onload = function() {document.getElementById('myImg').appendChild(imgObj); };
}, 300);

Categories

Resources