drawing image on html5 canvas - html

I'm pretty new to js and have only done a little bit of html however this seems like something that would be simple: I'm just trying to draw an image onto a canvas! If adding the new image to my main div (gameObjectElement) it works fine, but when trying to draw it on a canvas it doesn't show. The fill text shows up on the canvas so I believe the context stuff is correct.
var marthPic = new Image();
marthPic.src ='images/marth.jpg';
$(gameObjectElement).append(marthPic);
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.fillText("Hello World",300,50);
ctx.drawImage(marthPic, 100, 100);
Any ideas?
thanks

You need to wait for the image to actually be loaded before you add it to the canvas. You can do this with an onload handler:
var marthPic = new Image();
marthPic.src ='images/marth.jpg';
$(gameObjectElement).append(marthPic);
marthPic.onload = function () {
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
ctx.font="30px Arial";
ctx.fillText("Hello World",300,50);
ctx.drawImage(marthPic, 100, 100);
};

Edited because I'm a noob (lucky cache hit):
<script>
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var marthPic = new Image();
marthPic.src = 'images/marth.jpg';
marthPic.onload = function() {
ctx.drawImage(marthPic,10,10);
};
</script>

Related

Work with image captured in webcam with canvas

I have a problem.
I need to capture a iamgem from my webcam, and work in canvas with this image.
my code is:
Webcam.set({
width: 640,
height: 480,
image_format: 'jpeg',
jpeg_quality: 90
});
Webcam.attach('#my_camera');
function take_snapshot() {
Webcam.snap(function (data_uri) {
var canvas = document.getElementById("results");
var ctx = canvas.getContext("2d");
ctx.beginPath();
ctx.drawImage(data_uri, 0, 0);
});
}
This is what I try and I know it is wrong.
So what I need to do to fix this?
drawImage() cannot draw data-uris directly so they have be converted to an image element first:
Webcam.snap(function (data_uri) {
var canvas = document.getElementById("results");
var ctx = canvas.getContext("2d");
var img = new Image(); // create an image element for data-uri
img.onload = function() { // add async handler
ctx.drawImage(this, 0, 0); // when loaded, draw image (this)
// goto next step from here as this block is async
};
img.src = data_uri; // set data-uri as source
});

Firefox bug - globalCompositeOperation not working with drawImage for an SVG element

I'm trying to create an 'eraser' effect in Canvas, but using an SVG image as a custom shape for the eraser.
So I can draw my SVG image to canvas, and use globalCompositeOperation='destination-out' to create a masking effect.
It works great in IE, Safari, and Chrome. But it utterly fails in Firefox.
function init() {
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var img = document.createElement('IMG');
img.onload = function () {
ctx.beginPath();
ctx.drawImage(img, 0, 0);
ctx.closePath();
ctx.globalCompositeOperation = 'destination-out';
}
img.src = "http://www.evanburke.com/FROST.png";
var svg = new Image;
svg.src = "http://www.evanburke.com/luf.svg";
function drawPoint(pointX,pointY){
ctx.drawImage(svg,pointX,pointY);
}
canvas.addEventListener('mousemove',function(e){
drawPoint(e.clientX,e.clientY);
},false);
}
<body onload="javascript:init();">
<div>
<canvas id="c" width="400" height="400"></canvas>
</div>
</body>
That's indeed a bug, and as advised by #RobertLongson, you should raise a bug in Mozilla's Buzilla.
But first, you should clean up your code : ctx.beginPath() is useless. and ctx.closePath() doesn't do what yo think it does.
If you want a workaround for this issue, you could first draw the svg image onto a canvas, then use this canvas as the eraser :
(function init() {
var canvas = document.getElementById('c');
var ctx = canvas.getContext('2d');
var svgCan;
var img = document.createElement('IMG');
img.onload = function() {
ctx.drawImage(this, 0, 0);
ctx.globalCompositeOperation = 'destination-out';
}
img.src = "http://www.evanburke.com/FROST.png";
var svg = new Image();
svg.src = "http://www.evanburke.com/luf.svg";
svg.onload = function() {
// create a canvas
svgCan = canvas.cloneNode();
svgCan.width = this.width;
svgCan.height = this.height;
// draw the svg on this new canvas
svgCan.getContext('2d').drawImage(svg, 0, 0);
}
function drawPoint(pointX, pointY) {
// this is now a pixel image that will work with gCO
ctx.drawImage(svgCan, pointX, pointY);
}
canvas.addEventListener('mousemove', function(e) {
drawPoint(e.clientX, e.clientY);
}, false);
})()
<div>
<canvas id="c" width="400" height="400"></canvas>
</div>

Adding JPEG layer to Canvas (using Caman)

I have an image that is manipulated using the Caman library.
I am trying to overlay a jpeg to the manipulated image.
I can see the jpeg appearing for a split second beneath the manipulated image, but it is quickly overlaid once the manipulated image fully loads.
No matter what order the code is in below, the overlay image lies beneath the manipulated image.
Is there an obvious solution to this? Thank you!
<script>
$(function() {
var canvas = document.getElementById('image1');
Caman("#image1", "pic.jpg", function () {
this.brightness(50).render();
});
//add text layer
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 69, 50);
};
imageObj.src = 'yoda.jpg';
});
</script>
Might need a little refactoring, but this is how I did it:
<script>
$(function() {
var canvas = document.getElementById('image1');
Caman("#image1", "pic.jpg", function () {
this.greyscale().render();
this.newLayer(function () {
var context = canvas.getContext('2d');
var imageObj = new Image();
imageObj.onload = function() {
context.drawImage(imageObj, 0, 0);
};
imageObj.src = 'overlay.png';
});
});
});
</script>

draw image on canvas

I am trying to put an image on a canvas. I read the following tutorial
https://developer.mozilla.org/en-US/docs/Web/Guide/HTML/Canvas_tutorial/Using_images
and tried to do something similar to it
my canvas is <canvas id="canvas" width="400" height="400"></canvas>
and I have created the function
function putImage(){
var img = new Image();
img.src = "./path.png";
var ctx = document.getElementById('canvas').getContext('2d');
ctx.drawImage(img,8,8);
}
but the image is not appearing on the canvas.
I have printed the image path and it is correct, so I was able to eliminate this issue.
any suggestions?
thanks
According to the tutorial, you're supposed to wrap your ctx.drawImage() inside img.onload like so
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.onload = function() {
ctx.drawImage(img, 0, 0);
};
img.src = '/files/4531/backdrop.png';
}
I hope this helps.
If you don't like to use Promise or onload you can also use EventListener:
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
var img = new Image();
img.addEventListener('load', function(){
ctx.drawImage(img, 0, 0);
});
img.src = '/files/4531/backdrop.png';
}
To add to Hass's answer: If you don't like the onload approach, you can await a Promise, like so:
async function draw() {
let ctx = document.getElementById("canvas").getContext('2d');
let url = "https://example.com/image.png";
let img = new Image();
await new Promise(r => img.onload=r, img.src=url);
ctx.drawImage(img, 0, 0);
}

Html 5 canvas update with KinetickJS

I am using KinetickJS to draw images on screen.
I have a layer on the stage, and recieve 1000 of images in base64 format.
First I try to draw them with Kinetic
Example 1, works fine BUT after 1000 of images when I try to drag or do something with layer it became veeeeeeeery slow.So I try next example
var imageObj = new Image();
imageObj.onload = function () {
var image = new Kinetic.Image({
x: imageInfo.LocationX,
y: imageInfo.LocationY,
image: imageObj,
width: imageInfo.Width,
height: imageInfo.Height,
name: "Update"
});
layer.add(image);
layer.draw();
};
imageObj.src = "data:image/jpeg;base64," + imageInfo.Image;
Example 2, but in this case canvas began blinking for each update
var imageObj = new Image();
imageObj.onload = function () {
var canvas = layer.canvas;
var context = canvas.getContext('2d');
// context.globalCompositeOperation = "destination-over";
context.drawImage(imageObj, imageInfo.LocationX, imageInfo.LocationY);
};
imageObj.src = "data:image/jpeg;base64," + imageInfo.Image;
So do you have any ideas how to make it faster and/or disable blinking?
The newest KineticJS 4.3 speeds up dragging and other functionality quite a lot. This would probably fix your problem.
http://d3lp1msu2r81bx.cloudfront.net/kjs/js/lib/kinetic-v4.3.0.min.js