Open borisreitman opened 8 years ago
Not sure what causes this. Please try these other libraries to see if the bug is WebcamJS specific:
Here are the screenshots:
First, another screenshot from webcamjs demo page, for comparison. It shows that the snapshot is squished.
HTML5 Webcam test page: https://simpl.info/getusermedia/
Flash Webcam test page: https://www.onlinemictest.com/webcam-test-in-adobe-flash
jQuery Webcam: http://www.xarg.org/project/jquery-webcam-plugin/ This is the first of the demos that also does a snapshot. You see that the snapshot is correct size.
Finally, JpegCamera: https://github.com/amw/jpeg_camera Also does a snapshot correctly. You can also see reported camera resolution of 960x540
Thank you for all these screenshots. Apparently WebcamJS has a bug, whereas all the others don't. I'll look into this as soon as I have time. Thanks!
@borisreitman I cannot reproduce this on any of my 3 MacBooks (2011 15", 2012 Retina 15", and 2013 Air 13"), all using the latest Chrome, and the built-in webcams.
Can you please provide me with:
Thanks!
Hi,
Strange, I spoke with someone on Skype and shared my screen (not video) and I think it caused fixing of the webcam. Now if I load your demo page, the camera starts at the long aspect ratio, as in my screenshot, but and then switches to a 320x240 ratio. And the snapshot is also correct.
I have version 10.10.4 (14E46) OSX Yosemite, MacBook Pro model A1278 I am using the built-in webcam.
I used Chrome browser in all screenshots. Version 47.0.2526.80 (64-bit)
I am going to try to get back into the bugged state.
I have restarted the computer but can't reproduce it. However, if I visit https://amw.github.io/jpeg_camera/demo/ I can see that my camera is at resolution of 1280x720
Therefore I conclude that webcamjs library doesn't read camera resolution, so that if some software places it into a weird resolution that I had of 960x540 (as my previous screenshot shows) then the library can't cope with it.
Wow, that is really bizarre. Yeah, you are correct, WebcamJS does not read the camera's native resolution (honestly I didn't even know you could), and all my test pages "force" it into a hard-coded size, usually 4:3 aspect ratio. Perhaps I should rethink that.
In my experience all the cameras I have tested automatically adjust to fit the aspect ratio in the page without distortion, but I see that is definitely not always the case.
Thanks for your help on this. I'll keep an eye on it, and think about redesigning the library to automatically adjust for the camera's native res.
Looking at jpeg_cam source, they get this by reading videoWidth and videoHeight attributes of the video DOM element.
From jpeg_cam source jpeg_camera_html5.coffee:
254 _wait_for_video_ready: ->
255 video_width = parseInt @video.videoWidth
256 video_height = parseInt @video.videoHeight
...
272 @_prepared(@video_width, @video_height)
And in jpeg_camera.coffee
361 _prepared: (video_width, video_height) ->
362 @video_width = video_width
363 @video_height = video_height
364
365 @_debug "Camera resolution #{@video_width}x#{@video_height}px"
Although I can't reproduce the original problem, I can reproduced squished snapshot with this:
Webcam.set({
width: 666, // live preview size
height: 500,
dest_width: 666, // device capture size
dest_height: 500,
crop_width: 500, // final cropped size
crop_height: 500,
image_format: 'jpeg',
jpeg_quality: 90
});
Yeah, that is a known issue with some webcams. They can only display and capture video at 4:3 aspect ratio (or sometimes 16:9 aspect if you go above a certain size threshold). If you want a square or other oddly shaped image, it's best to keep the width
, height
, dest_width
and dest_height
at 4:3 or 16:9 aspect depending on the size, and then use crop_width
and crop_height
to achieve the final desired image you want.
So to use your previous example, if you want a 500x500 image, you should set your camera to capture at 888x500. This is a 16:9 aspect rectangle fitted onto your 500x500 box with bleed. Then the library will crop a 500x500 box from the center of that image. Example:
Webcam.set({
width: 888, // live preview size
height: 500,
dest_width: 888, // device capture size
dest_height: 500,
crop_width: 500, // final cropped size
crop_height: 500,
image_format: 'jpeg',
jpeg_quality: 90
});
Demo page: https://pixlcore.com/demos/webcamjs/demos/500x500.html
This works for me without any warping / distortion. But please keep in mind that many webcams are different. They all have little quirks and resolution or aspect ratio rules. It's very difficult to achieve a universal solution that works perfectly for all cameras on all browsers.
Using suggested parameters work fine in all browsers except Firefox. In firefox, the snapshot image is distorted. The snapshot image is not squished, but opposite: stretched.
As a temporary solution I will just use 3/4 ratio rectangle, without any crop. That works on Firefox too..
I was also getting this issue on my MacBook Air but not on my iMac. The aspect ratio wasn't getting set properly, so when I captured an image it looked stretched.
Adding a 'constraint' seems to have fixed it for me.
options: {
width: 720,
height: 540,
image_format: 'jpeg',
jpeg_quality: 90
}
// Didn't work
WebCam.set(options)
// Working
WebCam.set('constraints', options)
You'd have to be an idiot to think all webcams are 4:3
Let's keep it civil @neaumusic. Not everyone is as smart as you.
I honestly think you should delete this repo, or rather everything but the actual shockwave to video source implementation. I opened another issue where there's a transform being applied on top of the already scaled video.
@neaumusic You've been reported to GitHub for abuse, and I am blocking you. I'm sorry this project didn't help you out. There are many webcam libraries out there. I hope you find what you are looking for.
@jhuckaby thanks lots for all the work you put into webcamjs, don't care about the trolls. is there anything we can do to help resolve this issue? our intended usage would greatly benefit from automatic aspect ratio detection
@jhuckaby Thanks a lot for webcam.js. I used this in my application.but the problem is image got stretched after capturing for ratio other than 4:3.How can I resolve this?
I am a newbbie in Javascript, and I am currently working with webcamjs. Before some days of research in internet, I found this solution for the issue of aspect ratio. After the camera is loading and before taking the snapshot, I put the following code to correct the aspect ratio in the destination canvas:
var videoTrack = Webcam.stream.getVideoTracks()[0];
const settings = videoTrack.getSettings();
Webcam.set('dest_width', Webcam.params.height * settings.aspectRatio);
I hope this can help you, best.
I can reproduce this as well,
Webcam.set ({
width: W,
height: H,
enable_flash: false,
image_format: 'jpeg',
jpeg_quality: 90
});
I have W > H; the lib creates the video with white padding on top and bottom, and when I snap it, inner contents of the video is scaled back to WxH without white bars.
Thanks @davidercoli. I try with your solution and it worked for me!
take in mind that the aspect ratio on iphone isn't available, but having the config of the camera you can set the dest with and height from camera itself so you will have the real values and after that with css you can show your image correctly depending on final resolution
const videoTrack = Webcam.stream.getVideoTracks()[0],
settings = videoTrack.getSettings();
// set values directly from camera
Webcam.set('dest_width', settings.width);
Webcam.set('dest_height', settings.height);
@xploshioOn this kind of does not work. I mean, you do get the snapshot with the correct aspect ratio with this, but the bars are still there in the preview, and if you do this 2nd time after Webcam.reset() the preview video loses bars but gets stretched
Hi there,
I was wondering if there is a way to avoid the stretching that occurs when using a mobile phone camera with webcamjs? It doesn't seem to matter which measurements I change in Webcam.set, the image still comes out stretched horizontally?
If you wonder what I mean, try using the webcamjs test page (https://pixlcore.com/demos/webcamjs/demos/500x500.html) with a mobile phone.
I'm really stumped here, grateful for any help.
@makc we added that on our solution and the camera doesn't show any bars, and we change camera from back and front and there is no issue after resetting Webcam, maybe is another issue in your case?
Hi, we use a third party solution which uses WebcamJS and it works great with some standard webcams. We wanted to improve the picture quality and I started to use elgato Cam Link 4K with either a Sony and a Canon camera. As far as I see I am having more or less the same problem like borisreitman had. As the software is used by a lot of people with the same configuration I guess adding something like
Webcam.set({
width: 888, // live preview size
height: 500,
dest_width: 888, // device capture size
dest_height: 500,
crop_width: 500, // final cropped size
crop_height: 500,
image_format: 'jpeg',
jpeg_quality: 90
});
will not work for everyone but cause problems for the now working environments. If I use camera setting 3:2 there is a black bar left and right and the aspect ratio changes and with 16:9 there is no black bar but the aspect ratio changes as well. Do you see any chance for a general workaround that would not have a negative impact on the already correct working cameras? Thanks for any help.
Regards
Niko
edit: What puzzles me is the fact that the preview is fine but the taken image has the wrong aspect ratio. As far as I see the output is always 16:9 whatever I set in the camera because of the framegrabber wich takes HDMI (which is probably 16:9 per default) and outputs USB. With 16:9 the following kind of works:
Webcam.set({
width: 853, // live preview size
height: 480,
dest_width: 1067, // device capture size
dest_height: 600,
crop_width: 800, // final cropped size
crop_height: 600,
image_format: 'jpeg',
jpeg_quality: 90
});
while
Webcam.set({
width: 640,
height: 480,
dest_width: 800,
dest_height: 600,
image_format: 'jpeg',
jpeg_quality: 90,
});
does not. So probably the task is somehow guess if the camera delivers 16:9 and then crop the image. Happy to hear any comments.
take in mind that the aspect ratio on iphone isn't available, but having the config of the camera you can set the dest with and height from camera itself so you will have the real values and after that with css you can show your image correctly depending on final resolution
const videoTrack = Webcam.stream.getVideoTracks()[0], settings = videoTrack.getSettings(); // set values directly from camera Webcam.set('dest_width', settings.width); Webcam.set('dest_height', settings.height);
Error in mounted hook: "TypeError: Cannot read property 'getVideoTracks' of undefined"
hey all. I just tried calling the drawImage without the width and height properties and seems to work.
so the drawImage call should be ctx.drawImage(canvas, 0, 0);
Seems to working for me, hope this helps.
Happy coding :)
This is the basic demo https://pixlcore.com/demos/webcamjs/demos/basic.html
I am using Macbook Pro. As you see that actual camera is shooting it a different aspect ratio. This would be half the trouble -- but the resulting image is wrong aspect ratio, as the real camera image is deformed into 320x240 when making the snapshot.