I have a really strange issue and I can't tell if it's an Android issue or something else.
Basically I have a video that plays and everytime pause is selected, I want to take a screen shot of the video using the HTML5 canvas technique drawImage() and add it to the canvas. This works perfectly on the first pause but after I start the video again and on any subsequent pause, drawImage() draws the image from the first time I paused to the canvas. The code works fine in Chrome/Firefox, just not on my Android device.
I have included the code below, any advice would be great.
document.addEventListener('DOMContentLoaded', function(){
document.getElementById('v').addEventListener('pause',myHandler,false);
function myHandler(e) {
if(!e) { e = window.event; }
//i even remove the canvas from the stage
$( '#c' ).remove();
//and re add a canvas to the dom
$('#canvasdrawer').html('<canvas id="c"></canvas>');
var canvas = document.getElementById('c');
var context = canvas.getContext('2d');
var cw = Math.floor(canvas.clientWidth / 100);
var ch = Math.floor(canvas.clientHeight / 100);
canvas.width = cw;
canvas.height = ch;
setTimeout(function(){
alert("timeout running");
//i have even tried to put it in a timeout to almost force refresh but that doesnt help
context.drawImage(document.getElementById('v'),0,0,cw,ch);
}, 2000);
}
},false);
Related
I am currently working on a project, where I have a locally hosted html page with a live video stream in it. I want to be able to capture a image from the video when pressing a button. The video is an html video element that gets its contents from hls.js. I already have a javascript function that is called when the button is clicked. The script uses a hidden canvas and sets its width and height to video.videoWidth and video.videoHeight. Then canvas.drawImage(video, 0, 0, video.videoWidth, video.videoHeight); is called to get an image of the video. I then get a link to the image with canvas.toDataURL('image/png'); and pass the link to the href of an tag.
The problem is, that the resulting image always is 300x150, while the video is 1920x1080. This obviously is not what I want. I want to have an image that is the same size as the video. I dont understand whats causing this.
I have confirmed that video.videoWidth and video.videoHeight return the correct values, by printing them to console.
I am really confused, because looking on the internet and googling a lot, shows that other people are using the exact same javascript lines as I am and are apparently not having this issue.
Here is my script:
function MouseDown(){
elmnt.style.backgroundColor = "black";
var canvas = document.getElementById("canvas");
var vid = document.getElementById("video");
canvas.width = vid.videoWidth;
canvas.height = vid.videoHeight;
var ctx = canvas.getContext('2d');
ctx.drawImage(vid, 0, 0, vid.videoWidth, vid.videoHeight);
console.log("Size: " + vid.videoWidth + "x" + vid.videoHeight);
var img = canvas.toDataURL('image/png');
var newimg = img.replace(/^data:image\/png/,'data:application/octet-stream');
var a = document.getElementById("imageLink");
a.setAttribute('download', 'Drone-Image.png');
a.href = newimg;
a.click();
}
Edit: Whatever the problem was, it resolved itself. When I started the computer that hosts the page today and tried again, it just worked...
I had tried a restart of the computer yesterday, but that didn't help...
I built a webapp to capture an image using getUserMedia(),
but the quality of the image is not so good, it's a little blurry!. I tried to take the picture via my phone's camera and there is a big difference!
I like to know why taking the picture from browser is not as good as taking it from the phone's camera! and if it's possible, how can it be done to get the image captured via browser (getUserMedia()) with the best quality?
capture.addEventListener('click', () => {
c.style.display = "flex";
c.width = video.outerWidth();
c.height = video.outerHeight();
ctx.drawImage(video, 0, 0, c.width, c.height);
video.style.display = "none";
})
Thanks in advance.
Try using these lines
c.width = video.videoWidth;
c.height = video.videoHeight;
Then your canvas will have the same resolution as the captured video. You can use CSS to scale the canvas appropriately for display, and most browsers do a good job of making the scaled display look good.
I already looked in these thread 1 and thread 2, but I still got the flickering when the mouse move.
My code:
function draw(){
var img = new Image();
img.src = "/Sample/Icons/sample.png";
img.onload = function () {
ctx.drawImage(img, X1, Y1, 25, 25);
};
}
Hopefully someone can give me an idea or solution on how to solve my flickering problem.
I'm assuming you're calling draw for each mousemove.
Mousemove events occur about 30 times a second so there is not enough time to load an image inside a mousemove handler.
Instead, load the image once at the start of your app.
Then ctx.drawImage has enough time to draw that preloaded image during each mousemove event.
I am drawing a video to a canvas and then drawing another image on top of it with a blend mode. So far my video works on chrome but not on firefox or safari. When I open with Firefox I see the blended canvas for a second and then it disappears. When I look in safari it shows the top image (which is a face)
I have an mp4 and a webm video uploaded to my website and when I inspect the code and show the video I can see that it is actually playing in firefox, which is confusing because it is like it has found the image and video data?
Is there something I need to do to get the video to work on all browsers?
Below is the code I am using and here is a link to the website (only works as supposed to in chrome at the moment) - http://chrisgjones.com/category/double-exposure/
var img1 = document.getElementById('img1'),
bg = document.getElementById('img2'),
canvas = document.getElementById("canvas"),
video = document.getElementById('video');
context = canvas.getContext("2d"),
blendMode = "multiply";
context.globalCompositeOperation = "source-over"; // dont apply blending to bg image
video.addEventListener('play', function () {
var $this = this; //cache
(function loop() {
if (!$this.paused && !$this.ended) {
context.drawImage($this, 0, 0, canvas.width, canvas.height);
setTimeout(loop, 1000 / 30); // drawing at 30fps
context.globalCompositeOperation = blendMode;
context.drawImage(img1, 0, 0, canvas.width, canvas.height);
}
})();
}, 0);
$(window).load(function(){
video.play();
});
I guess you mean setInterval instead of setTimeout. But anyway, better use requestAnimationFrame.
I've just recently started dabbling in HTML5/Javascript, and am currently trying to put together a simple blackjack game. My main browser is Chrome, and I'd noticed my draw function for cards wasn't working. I simplified the code quite a bit, but the drawImage() function still didn't seem to put anything on the screen.
$(document).ready(function(){
init();
});
function init(){
setCanvas();
}
function setCanvas(){
var canvas = document.getElementById("game-canvas");
var context = canvas.getContext("2d");
canvas.width = 800
canvas.height = 600
context.fillStyle = "#004F10";
context.fillRect(0,0,800,600);
var back = new Image();
back.src = "testermed.png"
context.drawImage(back,54,83);
}
Now when I run this in Chrome, I get the box drawn by the context but NOT the image drawn. However when I run it in Firefox the image and box show up just fine. From what I can tell Firefox and Chrome both support HTML5 canvas equally; any ideas as to why it won't work on Chrome?
Try to write instead of context.drawImage(...) this:
back.onload = function() {
context.drawImage(back, 54, 83);
}