How to insert logo in the center of qrcode in Python?
Asked Answered
B

4

9

I am using pyqrcode module in python and generating QR code with it. How to put the logo in the center of that QR code.

The code looks like this

import pyqrcode
data = "Hello World!!"

number = pyqrcode.create(data)
number.png('xyz.png', scale=int(scale))

with open('xyz.png', "rb") as f:
    return HttpResponse(f.read(), content_type="image/png")

Or is there any another way of doing this instead of pyqrcode?

Bucella answered 3/8, 2017 at 10:45 Comment(2)
Possible duplicate of How do you composite an image onto another image with PIL in Python?Kanishakanji
Dont you think that qr code will create problem, if I do that?Bucella
U
18

If you use a high-redundancy algorithm (eg H), you can damage the generated QRCode up to a certain percentage. H means you can cover 30% of the data and it'll still work.

That means it's just a case of placing your image over the code. The format is up to you.

enter image description here

import pyqrcode
from PIL import Image
url = pyqrcode.QRCode('http://www.eqxiu.com',error = 'H')
url.png('test.png',scale=10)
im = Image.open('test.png')
im = im.convert("RGBA")
logo = Image.open('logo.png')
box = (135,135,235,235)
im.crop(box)
region = logo
region = region.resize((box[2] - box[0], box[3] - box[1]))
im.paste(region,box)
im.show()
Unerring answered 3/8, 2017 at 16:20 Comment(1)
would you mind providing reference or explanation to the croping and resizing,Alchemy
V
9

Though this question is more than 1 year old now, but still I am posting my solution as I got it working hoping that it might help someone else.

CAUTION I generated the qr code image in png format. To get it working, pypng module must be installed.

import pyqrcode
from PIL import Image

# Generate the qr code and save as png
qrobj = pyqrcode.create('https://stackoverflow.com')
with open('test.png', 'wb') as f:
    qrobj.png(f, scale=10)

# Now open that png image to put the logo
img = Image.open('test.png')
width, height = img.size

# How big the logo we want to put in the qr code png
logo_size = 50

# Open the logo image
logo = Image.open('stackoverflow-logo.jpg')

# Calculate xmin, ymin, xmax, ymax to put the logo
xmin = ymin = int((width / 2) - (logo_size / 2))
xmax = ymax = int((width / 2) + (logo_size / 2))

# resize the logo as calculated
logo = logo.resize((xmax - xmin, ymax - ymin))

# put the logo in the qr code
img.paste(logo, (xmin, ymin, xmax, ymax))

img.show()
Vichy answered 25/8, 2018 at 21:33 Comment(4)
the logo can occupy how many of the area without messing the data?Basanite
@GuilhermeHenriqueMendes That I didn't check. You can check it by gradually increase the logo size until it stops scanning :)Vichy
30% checked! =)Basanite
this should be the accepted answerGottwald
C
1

There seems to be a much simpler way of doing this. The QRCode documentation already explains how to do this.

import qrcode
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers.pil import RoundedModuleDrawer
from qrcode.image.styles.colormasks import RadialGradiantColorMask

qr = qrcode.QRCode(error_correction=qrcode.constants.ERROR_CORRECT_L)
qr.add_data('Some data')

img_1 = qr.make_image(image_factory=StyledPilImage, module_drawer=RoundedModuleDrawer())
img_2 = qr.make_image(image_factory=StyledPilImage, color_mask=RadialGradiantColorMask())
img_3 = qr.make_image(image_factory=StyledPilImage, embeded_image_path="/path/to/image.png") # this one

https://github.com/lincolnloop/python-qrcode#styled-image

Carbamidine answered 3/2, 2024 at 0:20 Comment(1)
I came here because this solution doesn't work in my case. Still gave + 1 because the answer is technically correct.Insinuating
C
-1

This can be done quite easily with css. Set the qr code container class to position: relative; and include an img / svg within that container with position: absolute; and transform it to the center. Restrict the size of the overlay to prevent the QR code from being unreadable.

https://jsfiddle.net/xf7d058c/

<!-- CSS -->
.container { width: 400px; height: 400px; border: 1px solid green; position: relative; }
.transform { position: absolute; left: 50%; top: 50%; transform:translate(-50%, -50%); }

<!-- HTML -->
<div class="container">
  <svg height="20" width="20" class="transform"><circle cx="5" cy="5" r="5" fill="#802929" /></svg>
</div>
Caller answered 29/7, 2020 at 9:41 Comment(0)

© 2022 - 2025 — McMap. All rights reserved.