QR Code ******* QR Code is a 2D symbology widely used for URLs and contact details. See also: QR code on Wikipedia for background on the symbology itself. Note: The QR support in pyStrich is less actively maintained than the other symbologies. If your project's main need is QR codes, consider whether python-qrcode is a better fit -- it has a larger feature set (logos, styled modules). pyStrich's QR support is most useful when you also need one of its other symbologies and want a single dependency. Example ======= from pystrich.qrcode import QRCodeEncoder encoder = QRCodeEncoder("https://github.com/mmulqueen/pyStrich") encoder.save_svg("qrcode-example.svg") [image: QR code encoding the pyStrich GitHub URL.][image] Sizing and quiet zone ===================== The "cellsize" argument to "save()" and "get_imagedata()" sets the pixel side length of one module (default "5"). See also: Printing barcodes for guidance on selecting "cellsize" for printed output. encoder = QRCodeEncoder("https://github.com/mmulqueen/pyStrich") encoder.save("qrcode-large.png", cellsize=10) [image: QR code encoding the pyStrich GitHub URL rendered with cellsize=10.][image] Output formats ============== SVG output ---------- For embedding in web pages or any workflow that benefits from resolution-independent output, use "save_svg()" (or "get_svg()" to receive the SVG as a string). from pystrich.marks import MarkShape QRCodeEncoder("https://github.com/mmulqueen/pyStrich").save_svg("qr.svg") QRCodeEncoder("https://github.com/mmulqueen/pyStrich").save_svg( "qr-circles.svg", mark_shape=MarkShape.CIRCULAR_CELLS ) The SVG's "viewBox" is in module units, while "width" and "height" scale by "cellsize". The "mark_shape" keyword selects how matched cells are drawn -- horizontal runs of rectangles (the default) or one filled circle per cell. Note: Circular cells fall outside the standard module shape and decoder support varies. Test with your target scanner before deploying. Added in version 0.12. PNG output ---------- For raster output, use "save()" to write a PNG file or "get_imagedata()" to receive the raw PNG bytes. QRCodeEncoder("https://github.com/mmulqueen/pyStrich").save("qrcode.png") EPS output ---------- For embedding in LaTeX ("\includegraphics") or other vector print workflows, use "save_eps()" (or "get_eps()" to receive the EPS as a string). QRCodeEncoder("https://github.com/mmulqueen/pyStrich").save_eps("qr.eps") The "cellsize" argument is the side length of one module in PostScript points (1 point = 1/72 inch). Added in version 0.12. Terminal output --------------- For quick on-screen display, "get_terminal_art()" returns a scannable rendering using Unicode half-block characters. Each character represents two matrix rows and one column, so cells appear roughly square in a typical fixed-width terminal font. print(QRCodeEncoder("https://github.com/mmulqueen/pyStrich").get_terminal_art()) █▀▀▀▀▀█ █▄█▀▀▀▄ ███▀▀ █▀▀▀▀▀█ █ ███ █ ▄▀██ ▀ █▀▄ ▀█ █ ███ █ █ ▀▀▀ █ ▄█▄█▀█▀▀▀▀█▄ █ ▀▀▀ █ ▀▀▀▀▀▀▀ █ ▀ ▀▄█ ▀▄█ ▀ ▀▀▀▀▀▀▀ █ ▀▀ ▀▀█ ▄█▄▀▀▀▀█▀▀▄▄ █▄▄▀ ▀█ ▄█ ▄▀▀▀█ ▄ ▀▄█▄▄▀█▄▄█▄▀▄ ▀▀▄ █▄ ▄█▄▀▀▀█▀█▀▄ ███ █ ▄ ▀█▄▄ ▀▄▄█ ▀▀ █▀▄▄▀▄█ ▀██▄█▄▄ ▀█▀ ▄▀▀▄██▀▄▀▀█ ▀▄ ▄▀ ▀▀▀ ▄▀█▄█ ▄█▄██ ▀▀█▄ █ █▀▄▄ ▀ ███ █ ▀ ▀ ▀▀▀▄▀██ █▄▄▄██ █▀▀▀███▄▄ █▀▀▀▀▀█ █▄▄▀ ▀ █ ▀▀█ ▀ ██ █▄ █ ███ █ ▄▄█▄▄ █▄█▀▀▄▀█▀██▄▀ ▄ █ ▀▀▀ █ ▀▀ ▀██ ▄▀▀▀ █▄ █ ▄▀▄▀ ▀▀▀▀▀▀▀ ▀▀ ▀ ▀▀ ▀ ▀▀▀▀▀ ▀ By default the output is wrapped in ANSI escape codes that force a white background and black foreground, so the symbol scans regardless of the terminal's colour scheme. Pass "ansi_bg=False" for plain output (correct only on a light-themed terminal). Added in version 0.12. DXF (CAD) output ---------------- For direct part marking applications, "get_dxf()" returns a DXF representation of the symbol that CAD and CAM tools can read directly. The "cellsize" is in your chosen "units" (default ""mm"") rather than pixels. encoder = QRCodeEncoder("WDBCA45D2HA327260") with open("part.dxf", "w") as f: f.write(encoder.get_dxf(cellsize=0.5, units="mm")) The default "inverse=True" emits geometry for the light modules, including the quiet zone -- so the bounding box frames the symbol. Pass "inverse=False" to emit only the dark modules instead, matching the symbol's normal appearance; the bounding box then hugs the dark cells and the quiet zone has to be reintroduced downstream. Error correction level ====================== QR Codes embed redundant data so that a partly-damaged symbol can still be read. The error correction level (ECL) sets how much redundancy is added, and is one of: +------------+--------------------------------------------------------+ | ""L"" | Low: ~7% of codewords recoverable. Smallest symbol. | +------------+--------------------------------------------------------+ | ""M"" | Medium: ~15%. **Default** if "ecl" is not supplied. | +------------+--------------------------------------------------------+ | ""Q"" | Quartile: ~25%. | +------------+--------------------------------------------------------+ | ""H"" | High: ~30%. Largest symbol; tolerates the most damage. | +------------+--------------------------------------------------------+ Higher levels produce a denser symbol for the same payload (or, equivalently, require a larger symbol to fit the same payload), so pick the lowest level that meets your durability needs. ""H"" is typically reserved for symbols that may be partly obscured (e.g. by a logo) or printed on surfaces likely to be scratched, smudged or torn. QRCodeEncoder("https://en.wikipedia.org/wiki/Kings_River_(California)", ecl="H").save("qr-high.png") GS1 Digital Link ================ GS1 Digital Link encodes a GTIN (with optional batch, expiry, serial, ...) as a URL. It's just a URL -- pass it to "QRCodeEncoder" directly: QRCodeEncoder("https://id.gs1.org/01/05050070007664/10/W126").save("dl.png") Raw AI-syntax GS1 QR (FNC1 mode indicator) is not supported; for that, use Data Matrix. API === class QRCodeEncoder(text: str, ecl: Literal['L', 'M', 'Q', 'H'] | None = None) Bases: "Matrix2DEncoder"["int"] Encode a string as a QR Code 2D barcode. Typical use: encoder = QRCodeEncoder("https://d-nb.info/gnd/135514053") encoder.save("qr.png") Variables: * **matrix** -- 2D list describing the symbol prior to rendering. * **width** -- Pixel width of the most recently rendered image. * **height** -- Pixel height of the most recently rendered image. init_renderer() -> QRCodeRenderer Construct a "QRCodeRenderer" for the encoded matrix. Updates "width" and "height" with the renderer's dimensions and returns the renderer. get_ascii() -> str Return an ASCII-art rendering of the symbol. Return type: str get_dxf(cellsize: float = 1.0, inverse: bool = True, units: Literal['in', 'ft', 'mi', 'mm', 'cm', 'm'] | None = 'mm', *, mark_shape: MarkShape = MarkShape.SQUARE_CELLS) -> str Return a DXF (CAD) representation of the symbol. Parameters: * **cellsize** -- Side length of one module in "units". * **inverse** -- If "True" (the default), light modules are drawn as filled cells. If "False", dark modules are drawn, matching the normal appearance of the symbol. * **units** -- One of ""in"", ""ft"", ""mi"", ""mm"", ""cm"" or ""m"", or "None" for Unspecified ("$INSUNITS=0"). * **mark_shape** -- How matched cells are grouped and drawn. Return type: str Added in version 0.9. Changed in version 0.12: "units" now supports ""in"", ""ft"", ""mi"", ""cm"", ""m"" and "None" (Unspecified); previously any value other than ""mm"" was silently treated as unspecified. get_eps(cellsize: int = 5, *, inverse: bool = False, mark_shape: MarkShape = MarkShape.HORIZONTAL_RUNS) -> str Render the symbol and return EPS markup. Parameters: * **cellsize** -- Side length in PostScript points of one module. * **inverse** -- If "True", mark the light cells instead of the dark ones. * **mark_shape** -- How matched cells are grouped and drawn. Return type: str Added in version 0.12. get_imagedata(cellsize: int = 5) -> bytes Render the symbol and return PNG bytes. Parameters: **cellsize** -- Side length in pixels of one module. Returns: PNG-encoded image data. Return type: bytes get_pilimage(cellsize: int = 5) -> PIL.Image.Image Render the symbol and return a Pillow image. Parameters: **cellsize** -- Side length in pixels of one module. Returns: The rendered symbol. Return type: PIL.Image.Image Added in version 0.11. get_svg(cellsize: int = 5, *, inverse: bool = False, mark_shape: MarkShape = MarkShape.HORIZONTAL_RUNS) -> str Render the symbol and return SVG markup. Parameters: * **cellsize** -- Side length in user units of one module. * **inverse** -- If "True", mark the light cells instead of the dark ones. * **mark_shape** -- How matched cells are grouped and drawn. Return type: str Added in version 0.12. get_terminal_art(*, ansi_bg: bool = True) -> str Render the symbol using Unicode half-block characters for terminals. Each character represents two matrix rows and one column, producing approximately square cells in a typical fixed-width font and yielding a result that is scannable on screen. Parameters: **ansi_bg** -- If "True" (the default), wrap each line in ANSI escape codes that force a white background and black foreground, making the symbol scannable regardless of the terminal's colour scheme. Set to "False" for plain output (correct only on a light-themed terminal). Return type: str Added in version 0.12. save(filename: str | PathLike[str], cellsize: int = 5) -> None Save the symbol as a PNG. Pass a ".png" filename. Parameters: * **filename** -- PNG output path. * **cellsize** -- Side length in pixels of one module. save_eps(filename: str | PathLike[str], cellsize: int = 5, *, inverse: bool = False, mark_shape: MarkShape = MarkShape.HORIZONTAL_RUNS) -> None Save the symbol as an EPS file. Pass an ".eps" filename. Parameters: * **filename** -- EPS output path. * **cellsize** -- Side length in PostScript points of one module. * **inverse** -- If "True", mark the light cells instead of the dark ones. * **mark_shape** -- How matched cells are grouped and drawn. Added in version 0.12. save_svg(filename: str | PathLike[str], cellsize: int = 5, *, inverse: bool = False, mark_shape: MarkShape = MarkShape.HORIZONTAL_RUNS) -> None Save the symbol as an SVG file. Pass a ".svg" filename. Parameters: * **filename** -- SVG output path. * **cellsize** -- Side length in user units of one module. * **inverse** -- If "True", mark the light cells instead of the dark ones. * **mark_shape** -- How matched cells are grouped and drawn. Added in version 0.12.