0
# Styling and Customization
1
2
Advanced styling capabilities for QR codes including custom module shapes, color masks, embedded images, gradients, and various drawing patterns through the StyledPilImage factory and associated styling components.
3
4
## Capabilities
5
6
### Styled PIL Image Factory
7
8
The StyledPilImage factory provides comprehensive styling capabilities with support for custom module drawers, color masks, and embedded images.
9
10
```python { .api }
11
from qrcode.image.styledpil import StyledPilImage
12
13
class StyledPilImage:
14
"""
15
Advanced styled PIL image factory with extensive customization options.
16
17
Features:
18
- Custom module drawer shapes
19
- Color masks and gradients
20
- Embedded images/logos
21
- Antialiasing support
22
- High-quality rendering
23
"""
24
25
kind = "PNG"
26
needs_processing = True
27
28
def __init__(self, *args, module_drawer=None, eye_drawer=None,
29
color_mask=None, embeded_image=None, embeded_image_path=None,
30
embeded_image_resample=None, **kwargs):
31
"""
32
Initialize styled PIL image factory.
33
34
Parameters:
35
- module_drawer: Custom drawer for QR code modules
36
- eye_drawer: Custom drawer for position detection patterns (eyes)
37
- color_mask: Color mask for advanced coloring effects
38
- embeded_image: PIL Image object to embed in center
39
- embeded_image_path (str): Path to image file to embed
40
- embeded_image_resample: PIL resampling filter for embedded image
41
"""
42
```
43
44
**Basic Usage Example:**
45
46
```python
47
import qrcode
48
from qrcode.image.styledpil import StyledPilImage
49
from qrcode.image.styles.moduledrawers import CircleModuleDrawer
50
from qrcode.image.styles.colormasks import SolidFillColorMask
51
52
# High error correction recommended for styled QR codes
53
qr = qrcode.QRCode(
54
error_correction=qrcode.constants.ERROR_CORRECT_H,
55
image_factory=StyledPilImage
56
)
57
qr.add_data('Styled QR Code')
58
qr.make()
59
60
img = qr.make_image(
61
module_drawer=CircleModuleDrawer(),
62
color_mask=SolidFillColorMask()
63
)
64
img.save('styled_qr.png')
65
```
66
67
### Module Drawers
68
69
Custom shapes for individual QR code modules (the small squares that make up the QR code).
70
71
```python { .api }
72
from qrcode.image.styles.moduledrawers import (
73
SquareModuleDrawer, CircleModuleDrawer, GappedSquareModuleDrawer,
74
RoundedModuleDrawer, VerticalBarsDrawer, HorizontalBarsDrawer
75
)
76
77
class SquareModuleDrawer:
78
"""Standard square modules (default)."""
79
80
class GappedSquareModuleDrawer:
81
"""Square modules with gaps between them."""
82
def __init__(self, size_ratio=0.8):
83
"""
84
Parameters:
85
- size_ratio (float): Size of squares relative to module space (0.0-1.0)
86
"""
87
88
class CircleModuleDrawer:
89
"""Circular modules."""
90
def __init__(self, size_ratio=0.8):
91
"""
92
Parameters:
93
- size_ratio (float): Size of circles relative to module space (0.0-1.0)
94
"""
95
96
class RoundedModuleDrawer:
97
"""Square modules with rounded corners."""
98
def __init__(self, radius_ratio=0.5):
99
"""
100
Parameters:
101
- radius_ratio (float): Corner radius relative to module size (0.0-1.0)
102
"""
103
104
class VerticalBarsDrawer:
105
"""Vertical bar modules."""
106
107
class HorizontalBarsDrawer:
108
"""Horizontal bar modules."""
109
```
110
111
**Module Drawer Examples:**
112
113
```python
114
import qrcode
115
from qrcode.image.styledpil import StyledPilImage
116
from qrcode.image.styles.moduledrawers import (
117
CircleModuleDrawer, GappedSquareModuleDrawer, RoundedModuleDrawer
118
)
119
120
qr = qrcode.QRCode(image_factory=StyledPilImage)
121
qr.add_data('Module Shapes')
122
qr.make()
123
124
# Circular modules
125
img1 = qr.make_image(module_drawer=CircleModuleDrawer())
126
img1.save('circles.png')
127
128
# Gapped squares
129
img2 = qr.make_image(module_drawer=GappedSquareModuleDrawer(size_ratio=0.6))
130
img2.save('gapped.png')
131
132
# Rounded corners
133
img3 = qr.make_image(module_drawer=RoundedModuleDrawer(radius_ratio=0.3))
134
img3.save('rounded.png')
135
```
136
137
### Color Masks
138
139
Advanced coloring systems for applying colors, gradients, and effects to QR codes.
140
141
```python { .api }
142
from qrcode.image.styles.colormasks import (
143
QRColorMask, SolidFillColorMask, RadialGradiantColorMask,
144
SquareGradiantColorMask, ImageColorMask
145
)
146
147
class QRColorMask:
148
"""
149
Base class for color masking effects.
150
151
Attributes:
152
- back_color: Background color (RGB tuple)
153
- has_transparency: Whether mask supports transparency
154
"""
155
156
back_color = (255, 255, 255) # White background
157
has_transparency = False
158
159
def get_fg_pixel(self, image, x, y):
160
"""
161
Get foreground color for pixel at (x, y).
162
163
Parameters:
164
- image: PIL Image being processed
165
- x, y (int): Pixel coordinates
166
167
Returns:
168
tuple: RGB or RGBA color tuple
169
"""
170
171
class SolidFillColorMask:
172
"""Solid color fill mask."""
173
def __init__(self, back_color=(255, 255, 255), front_color=(0, 0, 0)):
174
"""
175
Parameters:
176
- back_color (tuple): Background RGB color
177
- front_color (tuple): Foreground RGB color
178
"""
179
180
class RadialGradiantColorMask:
181
"""Radial gradient from center to edge."""
182
def __init__(self, back_color=(255, 255, 255),
183
center_color=(0, 0, 0), edge_color=(0, 0, 255)):
184
"""
185
Parameters:
186
- back_color (tuple): Background color
187
- center_color (tuple): Color at center
188
- edge_color (tuple): Color at edges
189
"""
190
191
class SquareGradiantColorMask:
192
"""Square gradient from center outward."""
193
194
class ImageColorMask:
195
"""Use another image as color source."""
196
def __init__(self, color_mask_image):
197
"""
198
Parameters:
199
- color_mask_image: PIL Image to use as color source
200
"""
201
```
202
203
**Color Mask Examples:**
204
205
```python
206
import qrcode
207
from qrcode.image.styledpil import StyledPilImage
208
from qrcode.image.styles.colormasks import (
209
SolidFillColorMask, RadialGradiantColorMask
210
)
211
from PIL import Image
212
213
qr = qrcode.QRCode(image_factory=StyledPilImage)
214
qr.add_data('Colorful QR')
215
qr.make()
216
217
# Solid colors
218
solid_mask = SolidFillColorMask(
219
back_color=(255, 255, 255), # White background
220
front_color=(0, 100, 200) # Blue foreground
221
)
222
img1 = qr.make_image(color_mask=solid_mask)
223
img1.save('solid_color.png')
224
225
# Radial gradient
226
gradient_mask = RadialGradiantColorMask(
227
back_color=(255, 255, 255), # White background
228
center_color=(255, 0, 0), # Red center
229
edge_color=(0, 0, 255) # Blue edges
230
)
231
img2 = qr.make_image(color_mask=gradient_mask)
232
img2.save('gradient.png')
233
```
234
235
### Embedded Images
236
237
Support for embedding logos or images in the center of QR codes with automatic sizing and positioning.
238
239
```python { .api }
240
# Embedded image parameters in StyledPilImage
241
def __init__(self, *args, embeded_image=None, embeded_image_path=None,
242
embeded_image_resample=None, **kwargs):
243
"""
244
Parameters:
245
- embeded_image: PIL Image object to embed
246
- embeded_image_path (str): Path to image file to embed
247
- embeded_image_resample: PIL resampling filter (default: LANCZOS)
248
249
Notes:
250
- Image is automatically sized to ~1/4 of QR code width
251
- Position is automatically centered
252
- High error correction recommended (ERROR_CORRECT_H)
253
- Supports alpha transparency
254
"""
255
```
256
257
**Usage Example:**
258
259
```python
260
import qrcode
261
from qrcode.image.styledpil import StyledPilImage
262
from PIL import Image
263
264
# High error correction for logo coverage
265
qr = qrcode.QRCode(
266
error_correction=qrcode.constants.ERROR_CORRECT_H,
267
image_factory=StyledPilImage
268
)
269
qr.add_data('https://example.com')
270
qr.make()
271
272
# Embed from file path
273
img1 = qr.make_image(embeded_image_path='logo.png')
274
img1.save('qr_with_logo.png')
275
276
# Embed PIL Image object
277
logo = Image.open('logo.png')
278
img2 = qr.make_image(embeded_image=logo)
279
img2.save('qr_with_pil_logo.png')
280
281
# Custom resampling filter
282
img3 = qr.make_image(
283
embeded_image_path='logo.png',
284
embeded_image_resample=Image.Resampling.NEAREST
285
)
286
img3.save('qr_pixelated_logo.png')
287
```
288
289
### Eye Customization
290
291
Separate styling for the position detection patterns (corner squares/"eyes") of QR codes.
292
293
```python { .api }
294
# Eye drawer parameter in StyledPilImage
295
def __init__(self, *args, eye_drawer=None, **kwargs):
296
"""
297
Parameters:
298
- eye_drawer: Custom drawer for position detection patterns
299
300
Notes:
301
- If not specified, uses same drawer as modules
302
- Eyes should remain recognizable for QR code scanning
303
- Be careful with heavy customization of eyes
304
"""
305
```
306
307
**Usage Example:**
308
309
```python
310
import qrcode
311
from qrcode.image.styledpil import StyledPilImage
312
from qrcode.image.styles.moduledrawers import CircleModuleDrawer, SquareModuleDrawer
313
314
qr = qrcode.QRCode(image_factory=StyledPilImage)
315
qr.add_data('Custom Eyes')
316
qr.make()
317
318
# Circular modules with square eyes
319
img = qr.make_image(
320
module_drawer=CircleModuleDrawer(),
321
eye_drawer=SquareModuleDrawer()
322
)
323
img.save('mixed_styles.png')
324
```
325
326
### SVG Drawer Aliases
327
328
SVG image factories also support custom drawers through aliases.
329
330
```python { .api }
331
from qrcode.image.svg import SvgImage
332
333
# Built-in SVG drawer aliases
334
drawer_aliases = {
335
"circle": ("SvgCircleDrawer", {}),
336
"gapped-circle": ("SvgCircleDrawer", {"size_ratio": 0.8}),
337
"gapped-square": ("SvgSquareDrawer", {"size_ratio": 0.8}),
338
}
339
```
340
341
**Usage Example:**
342
343
```python
344
import qrcode
345
from qrcode.image.svg import SvgImage
346
347
qr = qrcode.QRCode(image_factory=SvgImage)
348
qr.add_data('SVG Styling')
349
qr.make()
350
351
# Use drawer aliases
352
img = qr.make_image(module_drawer="gapped-circle")
353
img.save('svg_gapped_circles.svg')
354
```
355
356
### Advanced Styling Combinations
357
358
Combining multiple styling features for complex QR code designs.
359
360
**Complex Styling Example:**
361
362
```python
363
import qrcode
364
from qrcode.image.styledpil import StyledPilImage
365
from qrcode.image.styles.moduledrawers import RoundedModuleDrawer, SquareModuleDrawer
366
from qrcode.image.styles.colormasks import RadialGradiantColorMask
367
from PIL import Image
368
369
# Create highly styled QR code
370
qr = qrcode.QRCode(
371
version=None,
372
error_correction=qrcode.constants.ERROR_CORRECT_H, # High for logo
373
box_size=15, # Larger for detail
374
border=4,
375
image_factory=StyledPilImage
376
)
377
378
qr.add_data('https://example.com/styled')
379
qr.make()
380
381
# Complex styling combination
382
gradient_mask = RadialGradiantColorMask(
383
back_color=(240, 240, 240), # Light gray background
384
center_color=(255, 100, 50), # Orange center
385
edge_color=(50, 50, 200) # Blue edges
386
)
387
388
img = qr.make_image(
389
module_drawer=RoundedModuleDrawer(radius_ratio=0.4), # Rounded modules
390
eye_drawer=SquareModuleDrawer(), # Square eyes
391
color_mask=gradient_mask, # Gradient colors
392
embeded_image_path='company_logo.png' # Logo overlay
393
)
394
395
img.save('premium_qr.png')
396
```
397
398
### Performance Considerations
399
400
Styling features have different performance characteristics:
401
402
- **Module Drawers**: Minimal performance impact
403
- **Color Masks**: Moderate impact (pixel-by-pixel processing)
404
- **Embedded Images**: Light impact (simple overlay)
405
- **Complex Gradients**: Higher impact (mathematical calculations per pixel)
406
- **Antialiasing**: Higher impact (4x resolution processing)
407
408
**Optimization Tips:**
409
410
```python
411
# For best performance
412
qr = qrcode.QRCode(
413
box_size=10, # Smaller = faster
414
image_factory=StyledPilImage
415
)
416
417
# Simple styling (fastest)
418
img = qr.make_image(
419
module_drawer=SquareModuleDrawer(),
420
color_mask=SolidFillColorMask(front_color=(0, 0, 200))
421
)
422
423
# Complex styling (slower but higher quality)
424
img = qr.make_image(
425
module_drawer=CircleModuleDrawer(size_ratio=0.9),
426
color_mask=RadialGradiantColorMask(),
427
embeded_image_path='logo.png'
428
)
429
```