Javascript Creating an image element and drawing it in canvas - javascript

So I am trying to create an image element and then draw it onto a canvas with Javascript for an assingment. Here is my code
function drawCanvas() {
document.getElementById("heading").innerHTML = "Canvas Information";
document.getElementById("output").innerHTML = "";
clearCanvas();
var x = document.createElement("IMG");
x.setAttribute("src", "pudge.png");
var c = document.getElementById("myCanvas");
ctx = c.getContext('2d');
c.width = window.innerWidth;
c.height = window.innerHeight;
ctx.drawImage(x,0,0);
My problem is that for some reason, the code won't work on the first try, but after I run it once it will work fine, even if clear the canvas my other functions. I assume it can't create an image and then draw it on the canvas in one go, because if I put the image element straight into html with some id and call it like I did the canvas with getElementById then it works, but I wanted to create the element in the function itself without modifying the HTML. I tried creating a createImage() function with just
var x = document.createElement("IMG");
x.setAttribute("src", "pudge.png");
return x;
to no avail. Any help?
Edit: Sorry for the lack of code, this was an assignment so I didn't want to put out too much code that someone could find and copy. I was about to post it but someone answered already below with the eventlistener tip, TY guys!

You need to allow the image to load first. Once it loads, you can draw it to the canvas.
Add addEventListener('load', e => ...) to your image
function drawCanvas() {
document.getElementById("heading").innerHTML = "Canvas Information";
document.getElementById("output").innerHTML = "";
clearCanvas();
var x = document.createElement("IMG");
x.setAttribute("src", "pudge.png");
x.addEventListener('load', e => {
var c = document.getElementById("myCanvas");
ctx = c.getContext('2d');
c.width = window.innerWidth;
c.height = window.innerHeight;
ctx.drawImage(x, 0, 0);
})
}
Side note: Not sure if there is a difference, but you can use var x = new Image instead of document.createElement('img')

Related

Can't seem to get an old image off the canvas

I'm importing an image (that has to come in portrait) onto a canvas object, rotating it (because it's actually landscape) and running some OCR on the base64 from the canvas. That all works fine. However when I put a new image onto the canvas, the old one is retained and never replaced. I've tried clearRect, even gone to the extent of creating a new dom element each time and destroying it when I have everything I need (which is still in the code below) but I just cannot get the first image to clear.
Here's the relevant bit of the code
function onSuccess(imageURI) {
//CREATE NEW CANVAS ELEMENT
g = document.createElement('canvas');
g.setAttribute("id", "thePic");
g.style.overflow = "visible";
document.body.appendChild(g);
const canvas = document.getElementById('thePic'),
context = canvas.getContext('2d');
make_base();
function make_base()
{
base_image = new Image();
base_image.src = imageURI;
base_image.onload = function(){
const uriheight = base_image.naturalHeight;
const uriwidth = base_image.naturalWidth;
console.log(uriwidth + " " + uriheight);
context.canvas.width = uriheight;
context.canvas.height = uriheight;
context.drawImage(base_image, 0, 0);
//ROTATE THE IMAGE 90
context.clearRect(0,0,canvas.width,canvas.height);
context.save();
context.translate(canvas.width/2,canvas.height/2);
context.rotate(90*Math.PI/180);
context.drawImage(base_image,-base_image.width/1.2,-base_image.width/1.2);
context.restore();
var theCanvas = document.getElementById('thePic');
var rotImg = theCanvas.toDataURL();
var rotImg = rotImg.substring(21);
textocr.recText(4, rotImg, onSuccess, onFail);
function onSuccess(recognizedText) {
var recdata = recognizedText.lines.linetext;
var blockData = recognizedText.blocks.blocktext;
context.clearRect(0, 0, 10000,10000);
base_image = "";
rotImg = "";
document.getElementById('thePic').outerHTML = "";
document.getElementById('cgh').innerHTML = "";
}
}
}
Any advice much appreciated.
So it turned out to not be the canvas at all, it was image caching in a previous function that give the image to the canvas.
Thanks to everyone who took the time to have a squiz.

Loading image and resizing through canvas causes infinite loop

I want to get an image scaled correctly after loading it with a dummy click on a <input type='file'> and compressing it via drawing it onto a canvas. When calling a console.log() inside the img.onload I discovered it was being run in a loop. Putting the img.src = canvas.toDataURL("image/png") outside of the onload results in a blank image but no loop. Moving things around by trial and error has not been effective as I don't get the dynamics at play here (even though I can get images redrawn when rescaling a canvas). Thanks!
$('button.picture').on('click',function(){
var outerWrapper = $(this).closest('.outerWrapper')
$(this).siblings('.imageLoad').on('change', function(e){
var loadedImage = e.target.files[0]
var img = new Image();
img.src = window.URL.createObjectURL(loadedImage);
var canvas = document.createElement("canvas");
canvas.width = outerWrapper.width()
canvas.height = outerWrapper.height()
img.onload = function(e){
//still here the img.width returns the canvas width and not the original image's width
console.log(img.width)
var context = canvas.getContext("2d");
context.drawImage(img,0,0, canvas.width, canvas.height )
img.src = canvas.toDataURL("image/png")
}
$(this).closest('.outerWrapper').children('.imageWrapper').append(img)
})
$(this).siblings('.imageLoad').trigger('click')
})
To answer my own question I want to make clear what my aims were:
Load in image through a dummy click on an <input type="file">
Keeps the aspect ratio of the original image
Compress it
What worked was not setting img.src = canvas.toDataURL("image/png") as you would when resizing a canvas but by loading the original again image with URL.createObjectURL(loadedImage). To preserve the aspect ration I had to create two separate images, one to get the img.naturalWidth and img.naturalHeight for calculation and the next to load the image onto the canvas. Works a charm. Would be interested to learn where it can be refined.
$('button.picture').on('click',function(){
var outerWrapper = $(this).closest('.outerWrapper')
$(this).siblings('.imageLoad').on('change', function(e){
var loadedImage = e.target.files[0]
var img = new Image();
img.src = window.URL.createObjectURL(loadedImage);
var canvasPic = $('<canvas class="canvasPic"></canvas>')
canvasPic.prependTo(outerWrapper)
var canvas = canvasPic[0]
canvas.width = outerWrapper.width()
canvas.height = outerWrapper.height()
var context = canvas.getContext("2d");
var image = new Image();
image.onload = function(){
var w = img.naturalWidth
var h = img.naturalHeight
var ratio = h/w
var newWidth = canvas.height/ratio
context.drawImage(img,0,0,newWidth,canvas.height)
}
image.src = URL.createObjectURL(loadedImage);
})
$(this).siblings('.imageLoad').trigger('click')
})

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();

Drawing an image on the canvas in HTML5

I have been trying to get an image drawn on the canvas however have failed to do so. The HTML code simply creates the canvas element "canvas1" with no additional processing.
Here is the JS:
function loadlogo(){
var logo = new Image();
var canvas = document.getElementById('canvas1');
var context = canvas.getContext('2d');
//resize the canvas to the current window
context.canvas.width = window.innerWidth;
context.canvas.height = window.innerHeight / 3;
logo.src = "images/1.png";
logo.onload = function() {context.drawImage(logo,0,0;};
context.shadowOffsetX = 50;
context.shadowOffsetY = 30;
context.shadowColor = "pink";
}
window.addEventListener("load",loadlogo,false);
window.addEventListener("resize",loadlogo,false);
Any help you could give would be awesome!!!
I have tried this many ways and am stuck.
Thanks,
Bryan
Put your onload function for img before you assign img src
Change this part
{context.drawImage(logo,0,0;};
^ Notice the missing end-parenthesis here
to
{context.drawImage(logo,0,0)};
I would as QBM5 also recommend to put the src after setting onload to be sure it's properly initialized.

JavaScript, passing value to function

Kind of stuck with this thing, that's why need help please. I am using HTML5 and JavaScript to insert text on an image and create a new image with the text on it. Everything is fine if I am adding the text manually, however if I am trying to pass the text to the function as a value, its not happening. Here's the function code below
function draw_text(topt,bott){
var canvas = document.getElementById("e");
var context = canvas.getContext("2d");
var img = new Image();
img.src = "testimage.jpg";
img.onload = function()
{
context.drawImage(img, 0, 0);
draw_text();
};
var toptext = this.topt;
var bottomtext = this.bott;
context.font = "12px Arial";
context.fillStyle = "white";
context.strokeStyle = 'black';
context.fillText(toptext, (img.width-context.measureText(toptext).width)/2, 40);
context.strokeText(toptext, (img.width-context.measureText(toptext).width)/2, 40);
context.fillText(bottomtext, (img.width-context.measureText(bottomtext).width)/2, 350);
};
And I am calling this function by
draw_text('Text 1','Text 2');
But I either the canvas is not visible at all or it comes with the text 'Undefined'. What am I doing wrong? By the way, if it's any important I am doing this code in a codeigniter view file.
You are not using 'this' correctly.
Replace:
var toptext = this.topt;
var bottomtext = this.bott;
With:
var toptext = topt;
var bottomtext = bott;
***Also, I just noticed you have a recursive call to "draw_text()" with no parameters in the definition of draw_text, which is also a problem.

Categories

Resources