bitpay / cordova-plugin-qrscanner

A fast, energy efficient, highly-configurable QR code scanner for Cordova apps and the browser.
MIT License
568 stars 772 forks source link

Android: Scanning area limited to center of camera preview (portrait mode) #17

Open rocketman-21 opened 7 years ago

rocketman-21 commented 7 years ago

The scanner only detects the QR Code if it's in the middle of the camera preview. For example, if you position the camera so that the QRCode is in the upper right corner of the BarcodeView preview, the QR Code will not be detected. Once you move the camera so the QR Code is in the middle, it detects it instantly. Need to change the scanning area to take up as much of the camera preview as possible so the QR Code can be scanned from anywhere, not just the middle.

Edit: I just discovered that it scans the entire video preview when the camera is in landscape mode. This issue only occurs when the camera is in portrait mode.

rocketman-21 commented 7 years ago

@tobiasviehweger Any ideas?

NicRoy commented 7 years ago

Hi @willhay. Answering here your question on post #18 related to this post.

I have the same behaviour as you describe on my android devices. But surprisingly, QR code is scanned on ipad3 even if placed in corner (note that ipad3 has a strange way of using only a centered subportion of its photo captor when in video mode, making it equal to some kind of zoom).

Anyway, the behaviour with android does not appear to be a problem for me. As the plugin allows to overlay the video with custom HTML, it is quite easy to encourage the user to center the QRcode (as most scanners do with a box or centered cross).

(note : the QRcode does not need to be VERY centered on my Android tests, the tolerance zone seems fine to me, maybe you have a different behaviour).

bitjson commented 7 years ago

@NicRoy thanks for the info.

(As for the iOS "zoom" behavior, that's an OS level behavior. If you use the built-in Camera app, you'll notice it seems to "zoom" when you switch between photo and video. I'm not exactly sure why, but I assume Apple has a technical reason.)

I'll leave this issue open, as it would be great to get the Android platform working similarly to the iOS one (aggressively scanning the full screen).

tobiasviehweger commented 7 years ago

@willhay I just had a few minutes to look into this - though my time is unfortunately quite limited atm. I'd really like to test more.

My suspicion is that the following parts are responsible for this, the BarcodeView sets the cropping: https://github.com/journeyapps/zxing-android-embedded/blob/master/zxing-android-embedded/src/com/journeyapps/barcodescanner/BarcodeView.java#L178

The cropping comes from here: https://github.com/journeyapps/zxing-android-embedded/blob/master/zxing-android-embedded/src/com/journeyapps/barcodescanner/CameraPreview.java#L375

Especially this, where a 10% margin is added on each side, afterwards the height and width are adjusted to each other (height should not be larger than width), basically resulting in the issue (at least my guess) - this would also explain why it works in landscape (width always > height), but not in portrait. https://github.com/journeyapps/zxing-android-embedded/blob/master/zxing-android-embedded/src/com/journeyapps/barcodescanner/CameraPreview.java#L789

To validate this, it'd probably be best to create a new class which inherits from BarcodeView, but overrides getPreviewFramingRect or calculateFramingRect to return the whole view size - not sure about side effects though.

I'm also not too sure if this might be a bug in the library itself, it seems strange that this results to a very different experience for portrait/landscape, with no obvious explanation - might be a idea to raise an issue for them...

trinvh commented 7 years ago

+1

This should allow user define the limited area should be scanned and previewed by absolutely cordinates, such as https://manateeworks.com/barcode-scanner-sdk

r-bechara commented 5 years ago

Is it possible to set the region where scanner preview stays? I don't like it to get the entire screen, leaving no space for me to put other content on device's screen.

bitjson commented 5 years ago

@r-bechara not currently, but PR's are welcome! (Probably best to open a new issue, since that's a bit different than the topic of this issue.)

boemekeld commented 5 years ago

@tobiasviehweger thanks. in my case, the problem was in the viewport, "width = 375", getting around as follows:

<meta name="viewport" content="width=375, minimal-ui, user-scalable=0" id="viewport">

QRScanner.prepare(function (err, status) { if (status.authorized) { document.getElementById("viewport").setAttribute("content", "width=" + (window.screen.width * window.devicePixelRatio) + ", minimal-ui, user-scalable=0"); QRScanner.scan(function(err, text) { document.getElementById("viewport").setAttribute("content", "width=375, minimal-ui, user-scalable=0"); }); QRScanner.show(); } });