API Reference#

Decoders#

QRdecDecoder#

class deqr.QRdecDecoder#

QR code decoder using the QRdec backend.

Note

This decoder requires that input images have inverted reflectance in order to be able to decode them. The binarization defaults on decode() handle performing this inversion, but if either binarization or the inversion is disabled, images will not be decoded properly without preprocessing.

Raises

MemoryError – if the QR code reader context allocation fails.

decode(self, image_data, binarize: bool = True, binarize_invert: bool = True, convert_data: bool = True, unicode byte_charset: Optional[str] = u'utf-8') list[datatypes.QRCode]#

Decode all detectable QR codes in an image.

Warning

Binarization is done in-place on the image data buffer and changes the data. While this operation should be idempotent, it mutates the input data, which is a side effect.

Additionally, inverting during binarization is also done in-place on the image data buffer and is not idempotent, so if image data is reused, it will be re-inverted and not decode correctly the second time.

Parameters
  • image_data – A python object containing the pixel data of the image to search for QR codes. This can be any format supported by image.ImageLoader.

  • binarize – If True, binarize the input image (i.e. convert all pixels to either fully black or fully white). The decoder is unlikely to work properly on images that have not been binarized.

  • binarize_invert – If True, binarization inverts the reflectance (i.e dark pixels become white and light pixels become black).

  • convert_data

    If True, all data entry payloads are decoded into “native” python types:

    If False, no conversion will be done and all data entry data will be returned as bytes.

  • byte_charset – The charset to use for converting all decoded data entries of type datatypes.QRDataType.BYTE found in the image. If None, then data entries of type datatypes.QRDataType.BYTE will not be converted, even if convert_data is True.

Returns

A list of objects containing information from the decoded QR codes.

Raises
  • TypeError – if image_data is of an unsupported type.

  • ValueError – if image_data is malformed somehow.

QuircDecoder#

class deqr.QuircDecoder#

QR code decoder using the Quirc backend.

Raises

MemoryError – if the QR code reader context allocation fails.

decode(self, image_data, binarize: bool = True, binarize_invert: bool = False, convert_data: bool = True, unicode byte_charset: Optional[str] = u'utf-8')#

Decode all detectable QR codes in an image.

Warning

Binarization is done in-place on the image data buffer and changes the data. While this operation should be idempotent, it mutates the input data, which is a side effect.

Additionally, inverting during binarization is also done in-place on the image data buffer and is not idempotent, so if image data is reused, it will be re-inverted and not decode correctly the second time.

Parameters
Returns

A list of objects containing information from the decoded QR codes.

Raises
  • MemoryError – if the decoder image buffer allocation fails.

  • TypeError – if image_data is of an unsupported type.

  • ValueError – if image_data is malformed somehow.

Data Types#

These data types are structured collections of data produced by the decoders upon successfully decoding QR codes.

QRCode#

class deqr.datatypes.QRCode(version, ecc_level, mask, data_entries, corners, center)#

A structured collection of information about a QR code that has been decoded.

This class cannot usefully be instantiated by the user, but instances of it are created by deqr.QRdecDecoder.decode() or deqr.QuircDecoder.decode().

version: int#

The QR code version, which determines its size and data storage capacity.

ecc_level: QREccLevel#

The error correction code level of this QR code.

mask: int#

The data masking pattern used on the code.

data_entries: tuple[QRCodeData, ...]#

The data segments contained in this QR code.

deqr currently only produces data entries from segments that contain data, i.e. entries stored as QRDataType.NUMERIC, QRDataType.ALPHANUMERIC, QRDataType.BYTE, or QRDataType.KANJI

corners: tuple[tuple[int, int], ...]#

A sequence of pixel coordinates of the four corners of the QR code relative to the top-left of the image.

These coordinates always start with the corner containing the top-left finder pattern (relative to nominal “normal” QR code orientation). For example, if the QR code is upside down in the image, the first corner in this list of coordinates will actually be the bottom-right corner of the code’s position within the image.

center: tuple[int, int]#

The pixel coordinates of the geometric center of the QR code, relative to the top-left of the image. Coordinates are ordered (x, y), i.e. (horizontal, vertical).

QRCodeData#

class deqr.datatypes.QRCodeData(type, data)#

A data segment read from the QR code.

type: deqr.datatypes.QRDataType#

the type of QR code data, which also represents its storage format in the code, for types that contain data.

The QR code decoder backend is responsible for decoding the data into a meaningful byte sequence before providing it to the user, so this is mostly just metadata about how the data was stored in the QR code. See deqr.QRdecDecoder.decode() for details.

data: bytes#

The binary data contained in the segment.

QRDataType#

class deqr.datatypes.QRDataType(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

An enum.IntEnum representing the data storage format of a given data section.

QR codes can encode multiple different types of data with varying levels of efficiency. An individual QR code can also contain multiple different data sections, each with their own storage format.

See Wikipedia for more information.

NUMERIC = 1#

The data was stored as numeric (characters [0-9])

ALPHANUMERIC = 2#

The data was stored as alphanumeric ([0-9A-Z] and some)

BYTE = 4#

The data was stored as 8-bit bytes (normally a UTF-8 string)

KANJI = 8#

the data was stored as 13-bit kanji (Shift-JIS encoded)

QREccLevel#

class deqr.datatypes.QREccLevel(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)#

An enum.IntEnum representing the QR code’s error correction code (ECC) level.

This value represents how much error correction data the QR code contains, which directly maps to how much of the code can be missing or occluded while still permitting successful decoding.

The integer value matches the number encoded into the QR code itself, rather than corresponding to the amount of ECC data contained. QREccLevel.L contains the least data, followed by QREccLevel.M, QREccLevel.Q and QREccLevel.H in order of increasing amount of ECC data.

See Wikipedia for more information

M = 0#

The code can successfully decode with 15% of codewords missing.

L = 1#

The code can successfully decode with 7% of codewords missing.

H = 2#

The code can successfully decode with 30% of codewords missing.

Q = 3#

The code can successfully decode with 25% of codewords missing.

Image Loader#

class deqr.image.ImageLoader(data: Any)#

Load image data from common Python data containers.

This is responsible for manipulating image data into a format that the QR decoders can understand. Images are converted to 8-bytes-per-pixel grayscale and ordered as a 1-dimensional row-major array of data.

To avoid unnecessary hard dependencies on large external libraries, the source format of provided data is inferred by inspecting the object’s type description. Supported source formats include the numpy.ndarray used by numpy and OpenCV, the cv2.UMat format from OpenCV (this is converted to a numpy.ndarray), the PIL.Image.Image format used by Pillow, or, if all else fails, a tuple[bytes, tuple[int, int]] containing a pre-converted bytes object and its associated width, height pair.

Warning

It is strongly discouraged to access any of the properties of this class after it has been created. ImageLoader.data uses a different backing class depending on the source type (numpy.ndarray when coming from numpy or OpenCV, bytearray otherwise) and the QR code decoders may do in-place manipulation of the data (e.g. the binarization routine manipulates the data in place).

width: int#

The width, in pixels, of the image data stored in data

height: int#

The height, in pixels, of the image data stored in data

data: Union[bytearray, numpy.ndarray]#

The image binary data.

Binarize#

Note

The binarization function is expected to be invoked by the decoder as appropriate and not normally directly by the user, so it only offers a low-level interface.

deqr.binarize.binarize(uint8[::1] image, int width, int height, bool invert) void#

Binarize an image. Manipulation occurs in place, mutating the input data.

Parameters
  • image – a memoryview to the bytes of an image. For example, deqr.image.ImageLoader.data

  • width – the width, in pixels, of the input image.

  • height – the height, in pixels, of the input image.

  • invert – whether or not the output image should be light/dark inverted.