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.
Related
In my android application, I have to show the images in thumbnail view with reduced size(100 KB) instead of showing it with original size(1 MB). It helps to improve the performance of my application.
How to implement this compression functionality using Ionic/ Cordova. Could you please provide some suggestion to implement this functionality.
Try this. It should work. But instead of image tag use canvas tag. Put this code in your javascript function for loading image. It compress your image to your desired dimensions.
img = new Image();
img.src = 'example.png'; // your file
img.onload = function(){
var canvas = document.getElementById('outputImage'); // id of your canvas
var ctx = canvas.getContext('2d');
canvas.width=400 // your dimensions
canvas.height=300
ctx.drawImage(img, 0, 0, canvas.width, canvas.height);
};
I am attempting to use javascript to take a picture with my iphone and draw the image to the canvas. I use
<input type="file" capture="camera" accept="image/*" id="takePictureField">
mobilePictureGet);
to use the camera. Once I choose a picture
document.getElementById("takePictureField").addEventListener('change', function(e) {
if(e.target.files.length == 1 && e.target.files[0].type.indexOf("image/") == 0) {
img.src = URL.createObjectURL(e.target.files[0]);
}
}
this fires, and the image appears how I want it in the tag. (so far so good), However, I draw it to the canvas when img tag has loaded:
img.onload = function() {
ctx.drawImage(img, 0, 0, img.width,img.height);
}
and it appears rotated -90 degrees. I have tried
var x = width / 2;
var y = height / 2;
var angleInRadians = Math.PI / 2;
ctx.translate(x, y);
ctx.rotate(angleInRadians);
ctx.drawImage(img, -width / 2, -height / 2, img.width, img.height);
ctx.rotate(-angleInRadians);
ctx.translate(-x, -y);
but I can't get it to fit.
Does anyone know why the canvas would draw the image rotated? Any help to get the picture drawn correctly on the canvas is much appreciated!!
Thanks!
It probably depends on how you hold your phone. That (orientation) information is stored in the exif data of the image and you have to rotate it accordingly.
One library that can help you with this is JavaScript Load Image
I've never tried to take a picture with javascript, but I do some ios mobile development.
The reason the picture comes out sideways at all, is because apple has deemed that holding your phone with the home button facing right is the only acceptable way to take a picture. This is also known as it's 'up' state.
More information on why your iPhone takes pictures sideways can be found here: http://rotatemailer.com/sideways-pictures.html
In ios it's very easy to rotate it, so in javascript i'm not too sure how to properly do that.
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 have an application where the users shoots or selects a picture and it gets displayed on a canvas (Cordova 3, iPhone4S) with Cordova Camera API.
Now I am experiencing a problem with image sizes. iPhone Screenshots, Landscape Photos, Portrait Photos all have different resolutions and sizes. And often the image gets cut or stretched in my canvas.
I tried it with image tag before. That worked well. But I am having problem with canvas.
At the moment I have
var canvas = document.getElementById("myCanvas");
canvas.width = 640;
canvas.height = 960;
canvas.style.width = "100%";
canvas.style.height = "100%";
It works if I load a screenshot in the canvas, but if I load a photo in the canvas it gets cut.
Here two photo examples (portrait and landscape) loaded from iPhone's photo library.
How it is:
How it should be:
(the one at the bottom)
How it is:
How it should be:
Any Idea how to get the canvas to display the full image with every ing size/resolution?
Thank you.
I figured it out myself. I just added targetWidth and targetHeight to the camera.getPicture function
var canvas = document.getElementById("myCanvas");
canvas.width = 600;
canvas.height = 960;
canvas.style.width = "300px";
canvas.style.height = "480px";
camera function
navigator.camera.getPicture(funcSuccess, funcError, { quality: 100, targetWidth: 600, targetHeight: 960, destinationType: destinationType.FILE_URI, sourceType: source });
In the success function:
canvas.drawImage(img, 0, 0);
anyway... because I am using different caves.width/height and canvas.style.with/height (for retina optimized) I now have another problem. My function to get the clicked pixels colors does not work properly.
I am using this (first answer): Get pixel color from canvas, on mouseover in my canvas tap event. But when using retina sizes it always returns false colors. Like it reads the pixels expecting that the image is 600x960 instead of 300x480 in an 600x960 pixel canvas.
Anyone any Idea?
In putting together a small canvas app I've stumbled across a weird behavior that only seems to occur in the default browser in Android.
When drawing to a canvas that has the globalCompositeOperation set to 'destination-out' to act as the 'eraser' tool, Android browser sometimes acts as expected, sometimes does not update the pixels in the canvas at all.
the setup:
context.clearRect(0,0, canvas.width, canvas.height);
context.drawImage(img, 0, 0, canvas.width, canvas.height);
context.globalCompositeOperation = 'destination-out';
draw a circle to erase pixels from the canvas:
context.fillStyle = '#FFFFFF';
context.beginPath();
context.arc(x,y,25,0,TWO_PI,true);
context.fill();
context.closePath();
a small demo to illustrate the issue can be seen here:
http://gumbojuice.com/files/source-out/
and the javascript is here:
http://gumbojuice.com/files/source-out/js/main.js
this has been tested in multiple desktop and mobile browsers and behaves as expected. On Android native browser after refreshing the page sometimes it works, sometimes nothing happens.
I've seen other hacks that move the canvas by a pixel in order to force a redraw but this is not an ideal solution..
Thanks all.
I did something like this, which forces the detachment of the canvas:
ctx.clearRect(0, 0, canvas.width, canvas.height);
if (isStockAndroid) {
canvas.style.display = "none";
canvas.offsetHeight;
canvas.style.display = "block";
}
That seems to be the most efficient as far as FPS is concerned. Otherwise it's the not-so-nice:
canvas.width = canvas.width;
...which seemed to also get it all working normally for me. Haven't tested to see if the first is essentially the same as the second and resets canvas settings, though, but it seems to be getting a higher frame rate? Anyway that definitely clears things. For the native detection stuff try here: How to detect only the native Android browser