Read qrcode from a web page with camera.

2019-02-09 06:01发布

问题:

Im looking for a solution to read a QRCode on a webpage.

Lets say I've generated with PHP and some library (zxing or something else) a QRCode and its printed on a piece of paper, ok?

What i would like to do now, is to read it back with tablet/smartphone throught a web-page. I browse to that page, it asks me to aim the QRCode with the camera, and then the scanned content is sent back to the page that decodes it.

There's something out there to handle this without the need to use an Android/iOS app? It could be another type of 2D barcode aswell, not exclusively a QRCode.

TY

回答1:

I have once worked with Lazarsoft's jsqrcode

It worked fine in the browser, and I know he made a demo to test on a phone with camera.

Here is his repository: https://github.com/LazarSoft/jsqrcode

For camera support: use the CamCanvas API: http://www.taboca.com/p/camcanvas/



回答2:

For me all tests with LazarSoft failed on all devices (it couldn't focus correctly). That's why I propose another solution here. It needs an app, BUT it is an existing one, so you don't have to write specific apps for the different devices.

Use the Barcode Scanner app by ZXing! Yes it is possible without a roundtrip to the server, contrary to what almost any source on the net is telling you. This app proved to be very reliable under various conditions (Volume+ to switch on the light) where other scanners failed. https://play.google.com/store/apps/details?id=com.google.zxing.client.android&hl=en

Limitations:

  1. The barcode scanner app and its callback mechanism currently only work on android and ios (others are planned).

  2. Obviously the solution only works on devices that have a camera and the app installed.

Solution:

  1. Trigger mechanism: The barcode scanner is opened when the following URI is opened: http://zxing.appspot.com/scan?...
  2. Callback: With ret=... a callback URI can be specified. This is the site with the code that is handling the scan, it is possible to use the same site that triggered the scanner, but it will be a little more complicated and not explained here (still no roundtrip to the server is needed). With {CODE} it is specified where the scanned data is inserted. Note that the callback URI has to be escaped.

    For example:

    http://zxing.appspot.com/scan?ret=http%3A%2F%2Ffoo.com%2Fscan.htm%23%7BCODE%7D (unescaped: ...ret=http://foo.com/scan.htm#{CODE})

    Important: You have to use the anchor # to retrieve the code, otherwise the solution is not going to work (because of caching, see below).

  3. Cache Manifest: Create a cache manifest, add scan.htm to the cached entries and add the manifest to site which opens the scanner (<html cache="foo.appcache">). Content of the file:

    CACHE MANIFEST
    
    CACHE:
    scan.htm
    
    NETWORK:
    *
    
  4. Process the scan: Here is an example for scan.htm:

    <!DOCTYPE html>
    <html>
      <head>
        <meta charset="UTF-8">
      </head>
      <body>
        <script>
          var code = window.location.hash.substr(1);
          ...
        </script>
      </body>
    </html>
    

Explanation

Because the site is cached, no roundtrip to the server is required. This works, because with # you are always on the same site, if you would pass the code like ?code=... then you would have to cache all possible codes.



回答3:

You can read QR Codes using instascan.

Copy instascan.min.js from the releases page and load with:

<script type="text/javascript" src="instascan.min.js"></script>

Sample code to read QR Code.

<!DOCTYPE html>
<html>
  <head>
    <title>QR Code Reader using Instascan</title>
    <script type="text/javascript" src="instascan.min.js"></script>
  </head>
  <body>
    <video id="preview"></video>
    <script type="text/javascript">
      let scanner = new Instascan.Scanner({ video: document.getElementById('preview') });
      scanner.addListener('scan', function (content) {
        console.log(content);
      });
      Instascan.Camera.getCameras().then(function (cameras) {
        if (cameras.length > 0) {
          scanner.start(cameras[0]);
        } else {
          console.error('No cameras found.');
        }
      }).catch(function (e) {
        console.error(e);
      });
    </script>
  </body>
</html>


回答4:

Instascan (https://github.com/schmich/instascan) has recently been published and solve many of the drawbacks of Lazarsoft's and the callback solution by @maraca. It uses HTML5 for camera and can be deployed off-line.