I'm using scriptcam and I have a problem with screenshot size only in IE10.
I init my webcam div with:
$("#webcam").scriptcam({
path: 'js/',
width: 640,
height: 480,
cornerRadius: 0
});
When I take a screenshot with
var image = new Image();
image.src = "data:image/png;base64," + $.scriptcam.getFrameAsBase64();
image.onload = function () {
ctx.drawImage(image, 0, 0);
};
my canvas has the photo resized at original value "320 pixels wide and 240 pixels high" and the other part is black.
How can I fix this problem??
Thanks for your help!
[UPDATE]
The problem is in the type of webcam: changing the webcam whit a HD cam, the size of the screenshot is ok. Is this a bug?
Related
I have this code in Fabric js, I have managed to crop image but when I load in the Canvas the cropped image is too small than the original image or Cropped Image. Another issue is after cropping some part are not cropped as selected.
fabric.Image.fromURL(imageUrl, function (img) {
var cropped = new Image();
cropped.src = canvas.toDataURL({
left: coodinates.xAxis,
top: coodinates.yAxis,
width: coodinates.width,
height: coodinates.height
});
cropped.onload = function() {
canvas.clear();
image = new fabric.Image(cropped);
image.left = coodinates.xAxis;
image.top = coodinates.yAxis;
image.width = coodinates.width;
image.height = coodinates.height;
image.setCoords();
canvas.add(image);
canvas.renderAll();
};
});
I have tried using different options like drawing a Rectangle in the canvas but still did not resolve my issue.
I have a video player (video.js) in my application, and a function which takes a snapshot of the video.
The function create a canvas which draws the snapshot and convert the canvas into a DataURL.
But this doesn't work in Safari.
I'm getting a black screen on Safari.
the video tag looks like:
<video crossorigin="anonymous" playsinline="playsinline" id="player_2140_html5_api" class="vjs-tech" data-setup="{ "inactivityTimeout": 0 }" tabindex="-1" autoplay="autoplay" loop="loop"></video>
This is the function which creates the snapshot:
var canvas = document.createElement('canvas');
canvas.width = 640;
canvas.height = 480;
var ctx = canvas.getContext('2d');
var video = document.querySelector('video');
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
this.snapshotVideo = canvas.toDataURL('image/jpeg');
The generated dataUrl in Chrome is an image.
The generated dataUrl in Safari browser is a black rectangle.
In Safari the output is black instead of an image of the taken snapshot via the video, how can I solve this?
I resolved this problem on iOS...
I used setTimeout function:
setTimeout(() => {
ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
canvas.toBlob(() => {
this.snapshotVideo = canvas.toDataURL('image/jpeg');
});
},100);
Same here.
The problem seen first time at Safari 15. Before it works well with your code snipped.
See last comments here:
https://bugs.webkit.org/show_bug.cgi?id=181663
or here:
https://bugs.webkit.org/show_bug.cgi?id=229611
I have the same issue. Calling toDataURL on safari 15 up (mac, iPad or iPhone) seems to occasionally return "" blank string. Previous versions of safari work fine. I've checked that it is not exceeding the browser canvas size limits which would return "data:," but that is not causing the issue and is returning a blank string.
I got the same problem on Safari iOS 15.5 & 15.6 for handling image drawing.
After calling drawImage, the toDataURL() always return blank image.
I changed some code to avoid using canvas in the drawImage and use image object as the first parameter.
var scrollTop = 100;
var oc2 = document.createElement('canvas');
if (oc2.getContext) {
var octx2 = oc2.getContext('2d');
oc2.width = 200;
oc2.height = 300;
var img1 = new Image();
img1.onload = function() {
octx2.drawImage(img1, 0, scrollTop, 200, 300, 0, 0, 200, 300);
var bg_data = oc2.toDataURL('image/png');
if (bg_data) {
drawing_board.setImg(bg_data);
drawing_board.initHistory();
}
};
img1.src = oc.toDataURL('image/png');
}
Context
I'm trying to capture a snapshot through the client's video camera and save it as an image. I have a JSFiddle demo.
Problem
I'm not succeeding in getting the whole video area from the Video element to the Canvas with Context2D's drawImage. Althought the Video is 400 by 300
<video width="400" height="300" ...
and the canvas is the same 400 by 300
<canvas width="400" height="300" ...
and when I draw I specify for both source and target 400 by 300...
ctx.drawImage(video, 0, 0, 400, 300, 0, 0, 400, 300);
This is a sample of what is happening on my client.
The red framed element is the video and the green one is the canvas.
I suspect this is because the video stream is not 400 by 300 (not even 4:3 aspect ratio), but I couldn't find yet a solution for this or at least some indication in the HTML specs that this behavior is because of the video stream.
Does anyone have some more experience in this area and can point me in the right direction?
Sorry for the bad quality of the code in the fiddle.
When you set the HTMLElement's widthand height attributes, you're only setting its display size, not the size of the frame inside it.
Canvas2dContext.drawImage(video, x, y) will take the frame size, (which can be set by the mandatory of getUserMedia btw).
So you need either to set your canvas' width and height to the video.videoWidthand video.videoHeight properties to get the full quality image grabbed by the webcam, ot to call ctx.drawImage(video, 0,0, 400, 300) to rescale it on the canvas as it is scaled by CSS, or setting directly the mandatory during the getUserMedia call (latests specs are navigator.mediaDevices.getUserMedia(video: { width: 300, height:300 });) but unfortunately, for this latest, you can't be sure the browser will honor it, except by checking the video.videoHeight/Width ;-)
var ctx = rendering.getContext('2d');
btn.onclick = function() {
switch (select.value) {
case 'css rescale':
rendering.width = 400;
rendering.height = 300;
ctx.drawImage(video, 0, 0, 400, 300);
break;
case 'full quality':
rendering.width = video.videoWidth;
rendering.height = video.videoHeight;
ctx.drawImage(video, 0, 0);
break;
}
}
var initVideo = function(stream) {
video.src = URL.createObjectURL(stream);
video.play();
};
navigator.mediaDevices.getUserMedia({
video: true
})
.then(function(s) {
initVideo(s)
})
.catch(function(err) {
if (err.message.indexOf('secure origins') > -1) {
document.body.innerHTML = '<h3><a target="_blank" href="https://jsfiddle.net/x64ta5r3/">jsfiddle link for chrome and its https policy...</a></h3>(right click -> open Link...';
}
});
<button id="btn">take a snapshot</button>
<select id="select">
<option value="css rescale">css rescale</option>
<option value="full quality">full quality</option>
</select>
<video width="400" height="300" id="video"></video>
<canvas id="rendering"></canvas>
jsfiddle link for chrome and its https policy...
I'm having some issues using the drawImage method to place a pre-loaded image larger then 250PX width and height onto a canvas.
//Canvas
var canvas = document.createElement("canvas");
var contex = canvas_image.getContext('2d');
canvas.width = 350;
canvas.height = 350;
canvas.id = 'canvas'
$('.canvas').append(canvas);
//Draw Image to canvas
var imageObj = new Image();
imageObj.onload = new function() {
contex.drawImage(imageObj, 0, 0);
};
imageObj.src = $('img').attr('src');
I can't seem to get it to work with an image larger then 250PX Width or Height. But under 250 the image shows... It's really odd and frustrating.
You must get the context from the canvas element. The code you are showing in the post (not sure if it's a typo that happen when posting the question or not? though you shouldn't be able to draw anything if it's not a typo :-) ) has the following error:
This line:
var contex = canvas_image.getContext('2d');
should be:
var contex = canvas.getContext('2d');
as canvas_image does not seem to exist.
If you already have an image loaded you can draw that directly onto canvas instead - there is no need to do a second load of the image:
contex.drawImage($('img')[0], 0, 0);
just make sure you tap into its load event first as you do with the off-screen image.
var img = $('img');
img.on('load', function(e) {
contex.drawImage(img[0], 0, 0);
}
or call it on window's load event.
Other things to look out for is if the image actually has data in the 350x350 pixel area in top left corner (in case the image is very large). You can test by drawing it scaled to see if there is information there:
contex.drawImage(imageObj, 0, 0, canvas.width, canvas.height);
I am trying to replace any divs that have background images with canvas elements with those background images drawn onto them.
I've got the basics working but I am slightly stumped by the difference in image quality between the background-image on a div and the same image drawn onto a canvas.
Here is the code I am using to do this:
$('#container div').each(function(){
if($(this).css('background-image') != 'none'){
var bgImage = $(this).css('background-image').replace(/^url|[\(\)]/g, '');
var image = new Image();
var attrs = $(this)[0].attributes;
var dimensions = new Array();
var canvas = document.createElement('canvas');
dimensions.push($(this).height())
dimensions.push($(this).width());
$(canvas).attr('width',dimensions[0]);
$(canvas).attr('height',dimensions[1]);
$(canvas).css('background-image', 'none');
for(var i = 0; i < attrs.length; i++){
$(canvas).attr(attrs[i].nodeName,attrs[i].nodeValue);
}
var ctx = canvas.getContext('2d');
image.onload = function () {
ctx.drawImage(image, 0, 0, image.height, image.width);
}
image.src = bgImage;
$(this).replaceWith(canvas);
}
});
Here are the results:
It looks like the image is being stretched for some reason but I've tried to console.log the width/height of the image that I am using in drawImage and the values match up to the image dimensions. The results show just a crop of the image - the real one is 900x4000ish pixels.
Here is a jsfiddle link showing the problem in action:
http://jsfiddle.net/xRKJt/
What is causing this odd behaviour?
Ha! (took some seconds to figure out)
Image has naturalWidth and naturalHeight attributes which reflect its pixel dimensions. Change your code
image.onload = function () {
ctx.drawImage(image, 0, 0, image.naturalWidth, image.naturalHeight);
}
Because the image is so large, if you open the image in the browser it zooms out it by default. I think you'll get those zoomed out width and height attributes if you try to access image.width and image.height. Or something along the lines.