Creating a QR Code reader web service

in python •  7 years ago  (edited)

qrextract

QR codes are everywhere. I wrote this small web service to demonstrate how easy to create a web service using flask which scans the image file uploaded.

The code is at github

Reading part is done with zbar. Here there is a QRReader class which you initialize with the file name of the image you want scanned. Below is the complete listing for qrreader.py file.

import os
import zbar
import Image
from flask import jsonify

class QRReader:
    def __init__(self, fname):
        sc = zbar.ImageScanner()
        pil = Image.open(fname).convert("L")
        raw = pil.tobytes()
        w,h = pil.size
        self.img = zbar.Image(w,h,'Y800', raw)
        sc.scan(self.img)
        
    def __str__(self):
        cev = "<htm><pre>"
        for s in self.img:
            t = ""
            for x,y in s.location:
                t += "(%d, %d) " % (x,y)
            cev += t + " : " + s.data + " \n"
        return cev + "</pre></html>"

    def json(self):
        res = {}
        i = 0
        for s in self.img:
            res[i] = {"data": s.data, "location": (s.location[0], s.location[2]),
                          "count": s.count, "quality": s.quality, "type": "%s" % s.type, }
            i += 1            
        return jsonify(res)

The web server part was written using flask. It only allows using png, jpg and jpeg extensions. For the sake of simplicity, I didn't used fancy stuff like templates, css etc. I'm not a UI/UX guy. If you want to make it look better, it is on you.

The code has both presentation (ugly html form) and processing with QRReader class parts in one place.

The request.method tells us if this request is a GET or POST. If it is a GET request, then we will display the html form. If it is a POST request, it means that the form displayed is submitted. We just save the uploaded file and create a QRReader object using the file name. User can also request if the result should be delivered in HTML format or JSON format.

Here is the complete code for the web part:

import os
from flask import Flask, request, redirect, url_for, flash
from werkzeug.utils import secure_filename
from qrreader import QRReader

UPLOAD_FOLDER = '/tmp'
ALLOWED_EXTENSIONS = set([ 'png', 'jpg', 'jpeg'])

app = Flask(__name__)
app.config['UPLOAD_FOLDER'] = UPLOAD_FOLDER

def allowed_file(filename):
    return '.' in filename and  filename.rsplit('.', 1)[1].lower() in ALLOWED_EXTENSIONS

@app.route('/', methods=['GET', 'POST'])
def upload_file():
    if request.method == 'POST':
        # check if the post request has the file part
        if 'file' not in request.files:
            flash('No file part')
            return redirect(request.url)
        file = request.files['file']
        # if user does not select file, browser also
        # submit a empty part without filename
        if file.filename == '':
            flash('No selected file')
            return redirect(request.url)       
        if file and allowed_file(file.filename):
            filename = secure_filename(file.filename)
            f = os.path.join(app.config['UPLOAD_FOLDER'], filename)
            file.save(f)
            d = QRReader(f)
            outtype = request.form.get("outtype")
            if outtype == "json":
                return d.json()
            elif outtype == "html":
                return str(d)

    return '''
    <!doctype html>
    <title>Upload new File</title>
    <h1>Upload new File</h1>
    <form method=post enctype=multipart/form-data>
      <p><input type=file name=file>
      <p><input type=radio name=outtype value="json" checked>JSON
      <p><input type=radio name=outtype value="html" ">HTML
      <p><input type=text name=deneme value="denemedir">
      <p><input type=submit value=Upload>
    </form>
    '''

if __name__ == '__main__':
    app.run(host="0.0.0.0", port=5002,  debug=True)

Here is a sample picture with lots of qr codes.

sample.jpg

Below is the result for that document.

{
  "0": {
    "count": 0, 
    "data": "https://enttraining.macmms.com/?a=2691474", 
    "location": [
      [
        33, 
        635
      ], 
      [
        143, 
        744
      ]
    ], 
    "quality": 1, 
    "type": "QRCODE"
  }, 
  "1": {
    "count": 0, 
    "data": "https://enttraining.macmms.com/?a=2691477", 
    "location": [
      [
        696, 
        635
      ], 
      [
        806, 
        744
      ]
    ], 
    "quality": 1, 
    "type": "QRCODE"
  }, 
.
.
.
  "17": {
    "count": 0, 
    "data": "https://enttraining.macmms.com/?a=2691459", 
    "location": [
      [
        33, 
        31
      ], 
      [
        142, 
        141
      ]
    ], 
    "quality": 1, 
    "type": "QRCODE"
  }
}

To test the application, enter the command below,

python qr.py

then, open http://localhost:5002 on your browser.

Authors get paid when people like you upvote their post.
If you enjoyed what you read here, create your account today and start earning FREE STEEM!
Sort Order:  

Congratulations @ilkermanap! You received a personal award!

Happy Birthday! - You are on the Steem blockchain for 1 year!

You can view your badges on your Steem Board and compare to others on the Steem Ranking

Do not miss the last post from @steemitboard:

SteemitBoard - Witness Update
Vote for @Steemitboard as a witness to get one more award and increased upvotes!

You can download this Android QR code scanner app and use it on your phone https://www.appbrain.com/dev/qr+code+scanner/