lincolnloop / python-qrcode

Python QR Code image generator
https://pypi.python.org/pypi/qrcode
Other
4.25k stars 660 forks source link

PilImage returns wrong value for width #325

Open tomsoftware opened 1 year ago

tomsoftware commented 1 year ago

Using:

        qr=qrcode.QRCode(
            version=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
            box_size=4,
            border=3,
        )
        qr.add_data("Hallo")
        qr.make(fit=True)
        img = qr.make_image(fill_color="black", back_color="white", image_factory=PilImage)

        print(type(img))
        print(img.size, img.width, img.height)

prints:

<class 'qrcode.image.pil.PilImage'>
(108, 108) 21 108

So size[0] != width

I think the problem is that width and height are getter-functions https://github.com/python-pillow/Pillow/blob/d1731b35fed4e69158d98bffbf5a415f3a4cec8d/src/PIL/Image.py#L494

@property
    def width(self):

and something went wrong when calling them by getattr(self._img, name) https://github.com/lincolnloop/python-qrcode/blob/b80fea6ee7e75f3024b9ed7adf891a143e0b14e3/qrcode/image/pil.py#L53

Versions:

py --version Python 3.11.2

pip freeze colorama==0.4.6 numpy==1.24.2 pandas==1.5.3 Pillow==9.5.0 pypng==0.20220715.0 python-dateutil==2.8.2 pytz==2022.7.1 qrcode==7.4.2 six==1.16.0

JenusL commented 10 months ago

I also ran into this issue just now. img.width is returning the QR code dot width instead of the image pixels width. The issue is not with Pillow but instead that qrcode uses width in BaseImage: https://github.com/lincolnloop/python-qrcode/blob/b80fea6ee7e75f3024b9ed7adf891a143e0b14e3/qrcode/image/base.py#L24-L31 And since the PilImage is subclassing BaseImage, it will get that width. As you also can se above, the actual image object is located under self._img. So getting the width direectly from that works: img._img.width