Canvas drawImage() dimensions from video and image / mask - javascript

I've got a container with a video element and a mask image over it, that looks like the following:
<div id="container">
<img id="mask" src="/images/mask.png" width="1078" height="1508" />
<video autoplay="" id="video"></video>
</div>
As you guys can see the mask image is 1078px width and 1508px height. The video element is also 1078px width, but just 807px height (it doesn't have to be longer).
The canvas element haves the same width and height. When I try taking a snapshot of the video and draw that snapshot and a copy of the mask image to the canvas both elements are stretched way outside the canvas bounding.
var context = canvas.getContext('2d');
// Draw video
context.drawImage(video, 0, 0);
// Get mask image and draw mask
maskObj.src = document.getElementById("mask").src;
context.drawImage(maskObj, 0, 0);
I know I can pass more parameters trough the drawImage() function, but I do not know what that other parameters are exactly for. This article says you can just pass width and height as a integer. But if I do the following:
context.drawImage(video, 0, 0, 1078, 807);
context.drawImage(maskObj, 0, 0, 1078, 1508);
It is still draws the elements way outside the canvas bounding.
Can't really find out what I'm doing wrong so all the help is appreciated.
Example;

The only way it should happen is if you set the size of your canvas with css. Try to change the size of your canvas with the html attributes, or maybe add this :
canvas.width = 1078;
canvas.height = 1508;
var context = canvas.getContext('2d');
The resolution of a canvas only depends on those attributes. The css width and height just stretches it.

all you got to do is to get the video dimensions and set your canvas width and height to those values like below:
var video = document.getElementById('video');
canvas.height = video.videoHeight;
canvas.width = video.videoWidth;
var context = canvas.getContext('2d');
context.drawImage(video, 0, 0, canvas.width, canvas.height);

Related

Loading image into canvas - image scaled

I'm having a problem with loading image into canvas - the image is somehow scaled.
Background: I've got several canvases on my web page, I want to load images into them. When constructing, I'm not sure about the dimension, because the size depends on the screen size.
So I create div and canvas, use css to have it in the size that I want it to have and print an image onto the canvas. There would couple more things to do with the image (i.e. decide based on the ratio if I need to center it vertically or horizontally), but those are not really important at this point. The problem is that the image is rendered "zoomed".
Example: the javascript piece is here:
$("canvas").each(function() {
var context = $(this)[0].getContext('2d');
var img = new Image;
img.src = 'http://i67.tinypic.com/n38zdv.jpg';
$(img).load(function() {
context.drawImage(this, 0, 0);
});
//img will print 400 (correct, thats the width of the img)
//canvas will print based on the screen size (correct)
//img displayed in the canvas shows 300px out of 400px, it's zoomed (not correct)
$(this).parent().append(
'img width: '+img.width+
', canvas width: '+$(this).width());
});
I put the whole example with HTML and CSS to https://jsfiddle.net/7zdrfe58/11/.
I'm trying on Mac. Safari and Chrome work the same (i.e. with the zoom).
I would very appreciate help with this!! Thanks a lot
drawImage lets you specify the width and height of the image. You can get the canvas width like so:
$("canvas").each(function() {
var canvas = this;
var context = canvas.getContext('2d');
var img = new Image;
img.src = 'http://i67.tinypic.com/n38zdv.jpg';
$(img).load(function() {
context.drawImage(this, 0, 0, canvas.width, canvas.height);
});
});
Check out your working code here:
https://jsfiddle.net/ucxdLsq9/
The documentation of the drawImage signatures can be found here:
https://developer.mozilla.org/en/docs/Web/API/CanvasRenderingContext2D/drawImage
Give proper width and height to drawImage.
context.drawImage(this, 0, 0 ,300 ,160);
Updated Fiddle

showing one line on canvas which I draw before clear canvas

I am clearing canvas using ctx.clearRect(0,0,canvas.width,canvas.height) and just for debug I redraw after 2 seconds, on second time I redraw all content instead of lines. but it still showing one line on canvas which I draw lastly.
I have had problems before clearing a canvas by creating a full sized rectangle, so instead I use this more effective approach you may find helpful:
function clearCanvas(){
var context = canvas.getContext("2d");
context.clearRect(0, 0, canvas.width, canvas.height); //default
var w = canvas.width;
canvas.width = 1;
canvas.width = w; //Also change and re-apply canvas width
return;
}
Would you be able to post your full code?

JavaScript Canvas Disappears After Changing Width

After running this code:
var inventoryCanvas = document.getElementById("inventoryCanvas");
inventoryCanvas.width = width2;
it executes properly, however the canvas disappears when I run it.
Does anyone know the reason for this?
There is no way to stop this as it is expected behavior, I had a similar problem and solved it by creating a hidden buffer canvas. Before resize you can copy your original canvas to this buffer, resize the old canvas then redraw from the buffer.
Heres a quick fiddle demonstrating it:
http://jsfiddle.net/5keo7g2r/
var canvas = document.getElementById('canvas'),
buffer = document.getElementById('buffer'),
context = canvas.getContext("2d"),
bufferContext = buffer.getContext("2d");
bufferContext.drawImage(canvas, 0, 0); //Make a copy of the canvas to hidden buffer
canvas.width = 50; //Resize
context.drawImage(buffer, 0, 0); //Draw it back to canvas

How to paste canvas context on to a large plane

I've got a user resizeable window and canvas, I copy the canvas before sizing the canvas, then redraw it back, which works well when the user resizes the window bigger.
imageData = ctx.getImageData(0, 0, canvasWidth, canvasHeight);
canvasWidth = winW-20; // set new width
canvasHeight = winH-66; // set new height
canvas.setAttribute('width', canvasWidth);
canvas.setAttribute('height', canvasHeight);
ctx.putImageData(imageData, 0, 0);
Making the canvas smaller clips the data, how can I copy the canvas data on to a larger temporary plane for redraw big or small without clipping.
Use a secondary canvas element you create dynamically:
var tempCanvas = document.createElement('canvas'),
tempCtx = tempCanvas.getContext('2d');
tempCanvas.width = canvas.width;
tempCanvas.height = canvas.height;
tempCtx.drawImage(canvas, 0, 0);
... resize
ctx.drawImage(tempCanvas, 0, 0, canvas.width, canvas.height);
Just note that many of these operations will eventually reduce the quality so my recommendation would be that you use an off-screen canvas as above but you keep it at a single size through its life-time and then draw to that instead of the on-screen one, and update the on-screen one after each main operation. If this is practically feasible depends of course on your project.
The other approach is to store all draw operations as (custom) objects or something similar and then redraw the whole canvas in scale after each resize. This allow you to keep the data in vector format and get better quality when rasterized to canvas.

Problems calling drawImage() with svg on a canvas context object in Firefox

I basically want to transform my SVG into a PNG image. So I turn the SVG into an SVG image and try to draw that on a canvas to be able to get it as a PNG via the toDataURL() method. This works fine in Chrome, but in Firefox it produces a very uninformative error: NS_ERROR_NOT_AVAILABLE
After searching and experimenting a bit, I tried a different SVG source and all of a sudden everything worked fine. Any ideas what could cause the method to work fine for the first SVG string but fail for the second one? How can I change my SVG so that it will work?
Fiddle: http://jsfiddle.net/3AXwb/
var image = new Image();
image.src = 'data:image/svg+xml,' + escape(xml);
image.onload = function () {
var canvas = document.createElement('canvas');
canvas.width = image.width;
canvas.height = image.height;
var context = canvas.getContext('2d');
document.getElementById('container').appendChild(canvas);
context.drawImage(image, 0, 0);
}
Add a width attribute to the outer <svg> element. E.g. width="450"
The first case has width and height, the second only height and Firefox currently required both width and height to be present.

Categories