library icon indicating copy to clipboard operation
library copied to clipboard

Blurry & cant focus when scanned object is too close

Open lintangtimur opened this issue 3 years ago • 6 comments

With zxing android it so easy when i have small QR with dimension like 1x1 cm. Easy to scan, but when using zxing js more harder when camera cant read that QR. I think problem come from autofocus, is there any solution for keep focusing camera?

currently i'm using decodeContinously method

lintangtimur avatar Jun 19 '21 07:06 lintangtimur

Hey, is the problem with a Samsung phone? They today have multiple lenses and the ultravide lense does not have a focus. Try switching to a different lense.

fydelio avatar Jun 19 '21 09:06 fydelio

all phones, this is my code for scanning, is there any configuration to control focus and zoom?

codeReader.decodeFromInputVideoDeviceContinuously(selectedDeviceId, 'video', (result, err) => {

});

and if using xiaomi, permission to use camera is not allowed becoz Quickball from xiaomi settings

lintangtimur avatar Jun 19 '21 09:06 lintangtimur

Sorry, I didn't properly read your message (therefore I deleted my previous message). The problem regarding unfocused lenses are from the mobile phone and not related to this library. Many mobile phones ship with multiple lenses, which have a normal lense, a zoom lense and an ultrawide (which typically don't have an autofocus). So basically there is nothing you can do from a library perspective, except just selecting a different lense than an ultrawide (or for sure an focused lense).

fydelio avatar Jun 21 '21 06:06 fydelio

I'm having a similar issue, I find that I do get focus when the barcode is further away, but I think it's too small for the image detection to pick it up as it's only like 30% of the image. However I think that there is enough quality there for scanning, if there was a way to do some sort of "manual" zoom. By "manual" zoom, I mean take the middle 50% of the image - modern cameras are super high quality, so the image quality should still be enough, but the image will be further away and so will be in focus.

Does that make sense at all? Is it something that would be possible (although I'm using the library, I'm not very proficient with JS/HTML5).

sillyfrog avatar Jan 22 '22 03:01 sillyfrog

Looking into this further, I have ended up monkey patching the code with the following:


function start() {

    Startup stuff...

    codeReader.drawImageOnCanvas = function (canvasElementContext, srcElement) {
        var borderwidth = 0;
        var borderheight = 0;
        if (this.videozoom > 1) {
            var width = canvasElementContext.canvas.width;
            var height = canvasElementContext.canvas.height;
            var zoom = this.videozoom;
            canvasElementContext.drawImage(srcElement, (width - width / zoom) / 2, (height - height / zoom) / 2, width / zoom, height / zoom, 0, 0, width, height);

            var vidsize = video.getBoundingClientRect();
            var vidwidth = vidsize.width;
            var vidheight = vidsize.height;
            borderwidth = (vidwidth - vidwidth / zoom) / 2;
            borderheight = (vidheight - vidheight / zoom) / 2;
        } else {
            canvasElementContext.drawImage(srcElement, 0, 0);
        }
        videoborder.style.borderLeftWidth = borderwidth + "px";
        videoborder.style.borderRightWidth = borderwidth + "px";
        videoborder.style.borderTopWidth = borderheight + "px";
        videoborder.style.borderBottomWidth = borderheight + "px";
    }

    // Set a default zoom level
    codeReader.videozoom = 1;
}

function zoomin() {
    codeReader.videozoom += 0.5;
    if (codeReader.videozoom > 10) {
        codeReader.videozoom = 10;
    }
}

function zoomout() {
    codeReader.videozoom -= 0.5;
    if (codeReader.videozoom < 1) {
        codeReader.videozoom = 1;
    }
}

All the border stuff is totally optional, but I use it with the following HTML to give feedback to the user so they know what's actually getting used:

    <div id="supervideowrapper">
      <div id="videowrapper">
        <video id="video" playsinline autoplay style="width: 100%; height: auto;"></video>
        <div id="videoborder"></div>
      </div>
    </div>
    <button class="btn btn-secondary" onclick="zoomin();">+</button>
    <button class="btn btn-secondary" onclick="zoomout();">-</button>
  </div>
    #supervideowrapper {
      width: 100%;
      padding: 1em;
    }

    #videowrapper {
      display: table;
      width: 100%;
      position: relative;
    }

    #videoborder {
      position: absolute;
      left: 0%;
      right: 0%;
      top: 0%;
      bottom: 0%;
      margin: auto;
      border: 15px solid rgba(0, 0, 0, 0.6);

(You can see the full changeset here: https://github.com/sillyfrog/BGGManager/commit/7d3f42c0b6361cc3ffc7de8a7d77b766256e3a5d )

sillyfrog avatar Jan 23 '22 03:01 sillyfrog

Stale issue message

github-actions[bot] avatar Apr 29 '24 13:04 github-actions[bot]