backend.components.camera_verification.qrcode.qrcodeService

  1from flask import request, send_file, Response
  2import cv2
  3import numpy as np
  4import hashlib
  5from pyzbar import pyzbar
  6
  7from backend.components.utils.imageUtils import encode_image
  8
  9
 10def generate_qr_code(secret: str):
 11    '''
 12    Generates a QR code image from given secret.
 13
 14    **Parameters**:
 15    - `secret` (str): Secret to be encoded.
 16
 17    **Returns**:
 18    - `bytes`: QR code image bytes encoded as PNG 
 19    '''
 20    encoder = cv2.QRCodeEncoder().create()
 21    scale = 12
 22    qr = encoder.encode(secret)
 23
 24    qr = cv2.resize(qr, None, fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST)
 25
 26    border = 4 * scale
 27    qr = cv2.copyMakeBorder(
 28        qr, border, border, border, border,
 29        cv2.BORDER_CONSTANT, value=255
 30    )
 31
 32    _, qr = cv2.threshold(qr, 127, 255, cv2.THRESH_BINARY)
 33    return encode_image(qr)
 34
 35
 36def decode_qr_image(img) -> str:
 37    """
 38    Input an image loaded into numpy array and return decoded QR code data as string.
 39    Uses pyzbar.
 40
 41    **Parameters**:
 42    - `img` (ndarray): Decoded image in ndarray.
 43
 44    **Returns**:
 45    - `str`: Decoded QR code
 46    """
 47    decoded_texts = pyzbar.decode(img)
 48    if decoded_texts and len(decoded_texts)>0:
 49        valid_codes = [code for code in decoded_texts if code]
 50        count = len(valid_codes)
 51
 52        if count == 1:
 53            return valid_codes[0].data.decode("utf-8")
 54        elif count > 1:
 55            raise MultipleCodesError(f"Wykryto {count} kodów QR. Wymagany jest dokładnie jeden.")
 56        else:
 57            raise NoCodeFoundError("Wykryto wzorzec QR, ale nie udało się go odczytać.")
 58
 59    raise NoCodeFoundError("Nie wykryto kodu QR.")
 60
 61
 62@DeprecationWarning
 63def decode_qr_image_legacy(img) -> str:
 64    """
 65    [DEPRECATED] Input an image loaded into numpy array and return decoded QR code data as string.
 66    Uses cv2 detector.
 67
 68    **Parameters**:
 69    - `img` (ndarray): Decoded image in ndarray.
 70
 71    **Returns**:
 72    - `str`: Decoded QR code
 73    """
 74    qr_detector = cv2.QRCodeDetector()
 75    retval, decoded_info, points, straight_qrcode = qr_detector.detectAndDecodeMulti(img)
 76    if retval and decoded_info is not None:
 77        valid_codes = [code for code in decoded_info if code]
 78        count = len(valid_codes)
 79
 80        if count == 1:
 81            return valid_codes[0]
 82        elif count > 1:
 83            raise MultipleCodesError(f"Wykryto {count} kodów QR. Wymagany jest dokładnie jeden.")
 84        else:
 85            raise NoCodeFoundError("Wykryto wzorzec QR, ale nie udało się go odczytać.")
 86
 87    raise NoCodeFoundError("Nie wykryto kodu QR.")
 88
 89
 90class QRCodeError(Exception):
 91    """Base error class for QR codes"""
 92    pass
 93
 94class MultipleCodesError(QRCodeError):
 95    """Raised when more than one code is detected"""
 96    pass
 97
 98class NoCodeFoundError(QRCodeError):
 99    """Raised when no code is detected"""
100    pass
101
102class InvalidCodeError(QRCodeError):
103    """Raised when invalid code is detected"""
104    pass
105
106class ExpiredCodeError(QRCodeError):
107    """Raised when the QR code is expired"""
108    pass
def generate_qr_code(secret: str):
11def generate_qr_code(secret: str):
12    '''
13    Generates a QR code image from given secret.
14
15    **Parameters**:
16    - `secret` (str): Secret to be encoded.
17
18    **Returns**:
19    - `bytes`: QR code image bytes encoded as PNG 
20    '''
21    encoder = cv2.QRCodeEncoder().create()
22    scale = 12
23    qr = encoder.encode(secret)
24
25    qr = cv2.resize(qr, None, fx=scale, fy=scale, interpolation=cv2.INTER_NEAREST)
26
27    border = 4 * scale
28    qr = cv2.copyMakeBorder(
29        qr, border, border, border, border,
30        cv2.BORDER_CONSTANT, value=255
31    )
32
33    _, qr = cv2.threshold(qr, 127, 255, cv2.THRESH_BINARY)
34    return encode_image(qr)

Generates a QR code image from given secret.

Parameters:

  • secret (str): Secret to be encoded.

Returns:

  • bytes: QR code image bytes encoded as PNG
def decode_qr_image(img) -> str:
37def decode_qr_image(img) -> str:
38    """
39    Input an image loaded into numpy array and return decoded QR code data as string.
40    Uses pyzbar.
41
42    **Parameters**:
43    - `img` (ndarray): Decoded image in ndarray.
44
45    **Returns**:
46    - `str`: Decoded QR code
47    """
48    decoded_texts = pyzbar.decode(img)
49    if decoded_texts and len(decoded_texts)>0:
50        valid_codes = [code for code in decoded_texts if code]
51        count = len(valid_codes)
52
53        if count == 1:
54            return valid_codes[0].data.decode("utf-8")
55        elif count > 1:
56            raise MultipleCodesError(f"Wykryto {count} kodów QR. Wymagany jest dokładnie jeden.")
57        else:
58            raise NoCodeFoundError("Wykryto wzorzec QR, ale nie udało się go odczytać.")
59
60    raise NoCodeFoundError("Nie wykryto kodu QR.")

Input an image loaded into numpy array and return decoded QR code data as string. Uses pyzbar.

Parameters:

  • img (ndarray): Decoded image in ndarray.

Returns:

  • str: Decoded QR code
decode_qr_image_legacy = DeprecationWarning(<function decode_qr_image_legacy>)

[DEPRECATED] Input an image loaded into numpy array and return decoded QR code data as string. Uses cv2 detector.

Parameters:

  • img (ndarray): Decoded image in ndarray.

Returns:

  • str: Decoded QR code
class QRCodeError(builtins.Exception):
91class QRCodeError(Exception):
92    """Base error class for QR codes"""
93    pass

Base error class for QR codes

class MultipleCodesError(QRCodeError):
95class MultipleCodesError(QRCodeError):
96    """Raised when more than one code is detected"""
97    pass

Raised when more than one code is detected

class NoCodeFoundError(QRCodeError):
 99class NoCodeFoundError(QRCodeError):
100    """Raised when no code is detected"""
101    pass

Raised when no code is detected

class InvalidCodeError(QRCodeError):
103class InvalidCodeError(QRCodeError):
104    """Raised when invalid code is detected"""
105    pass

Raised when invalid code is detected

class ExpiredCodeError(QRCodeError):
107class ExpiredCodeError(QRCodeError):
108    """Raised when the QR code is expired"""
109    pass

Raised when the QR code is expired