From b0c529725ac536c23d8c3e5df62ff59ee75a51db Mon Sep 17 00:00:00 2001 From: Florian Festi Date: Mon, 20 Feb 2023 22:24:25 +0100 Subject: [PATCH] Add .qrcode() --- boxes/__init__.py | 16 +++++++++++ boxes/qrcode_factory.py | 61 +++++++++++++++++++++++++++++++++++++++++ requirements.txt | 1 + scripts/Dockerfile | 2 +- 4 files changed, 79 insertions(+), 1 deletion(-) create mode 100644 boxes/qrcode_factory.py diff --git a/boxes/__init__.py b/boxes/__init__.py index 4243ad1..2afff72 100755 --- a/boxes/__init__.py +++ b/boxes/__init__.py @@ -39,6 +39,8 @@ from boxes import pulley from boxes import svgutil from boxes.Color import * +import qrcode +from boxes.qrcode_factory import BoxesQrCodeFactory ### Helpers @@ -1533,6 +1535,20 @@ class Boxes: y * 0.5 * holedistance, 0.5 * diameter) + def qrcode(self, content, box_size=1.0, color=Color.ETCHING, move=None): + q = qrcode.QRCode(image_factory=BoxesQrCodeFactory, box_size=box_size*10) + q.add_data(content) + m = q.get_matrix() + tw, th = len(m) * box_size, len(m[0]) * box_size + print(tw, th) + if self.move(tw, th, move, True): + return + + self.set_source_color(color) + q.make_image(ctx=self.ctx) + + self.move(tw, th, move) + @restore def showBorderPoly(self,border,color=Color.ANNOTATIONS): """ diff --git a/boxes/qrcode_factory.py b/boxes/qrcode_factory.py new file mode 100644 index 0000000..3d62be1 --- /dev/null +++ b/boxes/qrcode_factory.py @@ -0,0 +1,61 @@ +from decimal import Decimal +import qrcode.image.base +import qrcode.image.svg + +class BoxesQrCodeFactory(qrcode.image.base.BaseImage): + """ + SVG image builder + Creates a QR-code image as a SVG document fragment. + """ + _SVG_namespace = "http://www.w3.org/2000/svg" + kind = "SVG" + allowed_kinds = ("SVG",) + + def __init__(self, *args, ctx=None, x=0, y=0, **kwargs): + super().__init__(*args, **kwargs) + self.ctx = ctx + self.x, self.y = x, y + # Save the unit size, for example the default box_size of 10 is '1mm'. + self.unit_size = self.units(self.box_size) + + def drawrect(self, row, col): + self.ctx.rectangle(*self._rect(row, col)) + self._img.append(self._rect(row, col)) + + def units(self, pixels, text=True): + """ + A box_size of 10 (default) equals 1mm. + """ + units = Decimal(pixels) / 10 + if not text: + return units + return '%smm' % units + + def save(self, stream, kind=None): + self.check_kind(kind=kind) + self._write(stream) + + def to_string(self): + return f"".join(self._img) + + def new_image(self, **kwargs): + self._img = [] + return self._img + + def _rect(self, row, col): + size = self.box_size / 10 + x = self.x + (row + self.border) * size + y = self.y + (col + self.border) * size + return x, y, size, size + + def _write(self, stream): + stream.write("".join(self._img)) + +if __name__=="__main__": + import qrcode + import qrcode.image + q = qrcode.QRCode(image_factory=BoxesQrCodeFactory, box_size=10) + q.add_data('hello') + ctx = "a context" + img = q.make_image(ctx="a context") + print(img.to_string()) diff --git a/requirements.txt b/requirements.txt index 597616b..7d059ea 100644 --- a/requirements.txt +++ b/requirements.txt @@ -3,3 +3,4 @@ markdown setuptools sphinx shapely>=1.8.2 +qrcode==7.3.1 diff --git a/scripts/Dockerfile b/scripts/Dockerfile index fc6a92f..7ee8af2 100644 --- a/scripts/Dockerfile +++ b/scripts/Dockerfile @@ -14,7 +14,7 @@ FROM fedora:latest # Install requirements -RUN dnf install -y git-core python3-markdown python3-setuptools python3-affine python3-shapely pstoedit && dnf clean all +RUN dnf install -y git-core python3-markdown python3-setuptools python3-affine python3-shapely python3-pillow python3-qrcode pstoedit && dnf clean all # Get Boxes.py sources to /boxes ARG BUILD_BRANCH=master