Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feat Request: Readable text, when using a small size QR images (like 'qr_version': 2) #11

Closed
loregood opened this issue May 5, 2021 · 4 comments · Fixed by #72
Closed
Labels
enhancement New feature or request

Comments

@loregood
Copy link

loregood commented May 5, 2021

When printing to a label printer with a small size strip (like 2 cm. in width), any text printed after the QR-code is unreadable -- especially if any text is long, like an URI. Since the text size currently also scales with the length of the text.

I'm not sure what the best approach would be, but I think it would be reasonable to assume that the height the QR-code is the limiting factor and then scale all text to fill "inside" the QR-codes height, and just ignore the length of the text. Another option could be to specify QR image size, and font/size independently of each other. Perhaps with a 'font_size': option in PLUGINS_CONFIG? It would be a little more fiddly to get a nice "QR-code and text" image, but you would have more control over the final image.

@loregood
Copy link
Author

loregood commented May 27, 2021

NetBox QR Code Plugin version

v0.0.5

NetBox version

v2.10.10

Python version

3.8.5

Steps to Reproduce

  1. Create a PLUGINS_CONFIG in your NetBox configuration.py file (with PLUGINS = ['netbox_qrcode'] enabled):
PLUGINS_CONFIG = {
    'netbox_qrcode': {
        'with_text': True,
        'qr_version': 2,
        'qr_box_size': 2,
        'device': {
            'text_fields': [
                'name'
            ]
        }
    }
}
  1. Create a Device in NetBox with a long name, like: 'Green Patch Panel 001-024'
  2. Create a Device in NetBox with a short name, like: '101-102'
  3. Find your devices, under Devices and look under "QR Code" field created by the NetBox QR Code Plugin
  4. Try to read the name printed next to the QR code for the device with a long name
  5. Compare with the short named device

Expected Behavior

When choosing 'with_text': True the text_fields should be readable when choosing a small size QR code, even for devices with a long name, if possible. If you try to print the QR code to a label printer with a small strip, to stick on the physical device, the name next to the QR is unreadable, if the text is long. The label printer, can't print so small text.

Observed Behavior

Your "QR code" field will look something like below, for the device with a long name:
Screen Shot 2021-05-27 at 09 26 06

Compared to the "QR code" field, for the device with a short name:
Screen Shot 2021-05-27 at 09 32 30

Suggested Behavior

I think it is reasonable to assume, that users of the NetBox QR Code Plugin would like print QR labels to attach to physical devices, like a 1U device in a rack. If they want text next to the QR code, it should be readable.

The limiting factor is (generally) the height of the QR code (not the length of the text). There are plenty of room to scale the text size to fill more of the height next to the QR code, as seen with the short named device above.

Perhaps an option like text_height in percent of the QR code or something like that, or an option not to scale the text size down, if it's long. I'm not sure what the best approach would be, but it would be really nice to have more control over the text size independently from the QR code size. When printing a small QR code, you can't really use text currently.

@k01ek k01ek added the enhancement New feature or request label May 27, 2021
@k01ek
Copy link
Collaborator

k01ek commented May 27, 2021

Hi @loregood ! Thanks for the feedback. I don't have enough time right now for this FR. I will look deep into it later.

@LHBL2003
Copy link
Contributor

I would also be happy about this FR. :)
I also just have the problem that the texts are barely readable.

@LHBL2003
Copy link
Contributor

While I have no idea about Pyton and NetBox plugins, I have a ready-made solution.

If font_size is specified in the configuration, the fixed font size is used. If no size is specified, then it will be adjusted to the QR code size.

configuration.py (Add 'font_size': 12,)

PLUGINS_CONFIG = {
    'netbox_qrcode': {
        'with_text': True,
        'text_fields': ['name', 'serial'],
        'font': 'ArialMT',
        'font_size': 12,

utilities.py (Decision whether as always or fixed font size)

def get_qr_text(max_size, text, font='TahomaBold', font_size=0):

    tmpimg = Image.new('L', max_size, 'white')
    text_too_large = True

    #If no Font Size in Config File, then Match the text to the QR Code
    if font_size == 0:

        font_size = 58

        while text_too_large:
            file_path = resource_stream(__name__, 'fonts/{}.ttf'.format(font))
            try:
                fnt = ImageFont.truetype(file_path, font_size)
            except Exception:
                fnt = ImageFont.load_default()

            draw = ImageDraw.Draw(tmpimg)
            w, h = draw.textsize(text, font=fnt)
            if w < max_size[0] - 4 and h < max_size[1] - 4:
                text_too_large = False
            font_size -= 1
    else:
        file_path = resource_stream(__name__, 'fonts/{}.ttf'.format(font))
        try:
            fnt = ImageFont.truetype(file_path, font_size)
        except Exception:
            fnt = ImageFont.load_default()

        draw = ImageDraw.Draw(tmpimg)
        w, h = draw.textsize(text, font=fnt)

    img = Image.new('L', (w, h), 'white')
    draw = ImageDraw.Draw(img)
    draw.text((0, 0), text, font=fnt, fill='black')
    return img

template_content.py (Config forward font_size value)

    def x_page(self):
        config = self.context['config']
        obj = self.context['object']
        request = self.context['request']
        url = request.build_absolute_uri(obj.get_absolute_url())
        # get object settings
        obj_cfg = config.get(self.model.replace('dcim.', ''))
        if obj_cfg is None:
            return ''
        # and ovverride default
        config.update(obj_cfg)

        qr_args = {}
        for k, v in config.items():
            if k.startswith('qr_'):
                qr_args[k.replace('qr_', '')] = v

        qr_img = get_qr(url, **qr_args)
        if config.get('with_text'):
            text = []
            for text_field in config.get('text_fields', []):
                cfn = None
                if '.' in text_field:
                    try:
                        text_field, cfn = text_field.split('.')
                    except ValueError:
                        cfn = None
                if getattr(obj, text_field, None):
                    if cfn:
                        try:
                            if getattr(obj, text_field).get(cfn):
                                text.append('{}'.format(getattr(obj, text_field).get(cfn)))
                        except AttributeError:
                            pass
                    else:
                        text.append('{}'.format(getattr(obj, text_field)))
            custom_text = config.get('custom_text')
            if custom_text:
                text.append(custom_text)
            text = '\n'.join(text)
            text_img = get_qr_text(qr_img.size, text, config.get('font'), config.get('font_size', 0))
            qr_with_text = get_concat(qr_img, text_img, config.get('text_location', 'right'))

            img = get_img_b64(qr_with_text)
        else:
            img = get_img_b64(qr_img)
        try:
            if version.parse(settings.VERSION).major >= 3:
                return self.render(
                    'netbox_qrcode/qrcode3.html', extra_context={'image': img}
                )
            else:
                return self.render(
                    'netbox_qrcode/qrcode.html', extra_context={'image': img}
                )
        except ObjectDoesNotExist:
            return ''

mhdask pushed a commit to mhdask/netbox-qrcode that referenced this issue May 29, 2024
…e is used.

If the font_size is not specified or if the value = 0, then the previous dynamic behavior will continue to be executed.

Issue netbox-community#11 from the original is related to the topic.
@mhdask mhdask mentioned this issue May 29, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants