1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
|
#!/usr/bin/env python
# -*- Mode: Python; coding: utf-8; indent-tabs-mode: nil; tab-width: 4 -*-
### BEGIN LICENSE
# This file is in the public domain
### END LICENSE
import qrencode
import Image
import ImageOps
import cairo
import array
class QRCodeSize(object):
SMALL = 120
MEDIUM = 230
LARGE = 350
class QRCode(object):
def __init__(self, output_size=QRCodeSize.MEDIUM):
self.output_size = output_size
self.qrcode_size = 0
self.pixel_size = 1
self.image = None
self.cr_surface = None
def encode(self, text):
return self._encode_to_pil(text)
def encode_to_cairo(self, text):
self._encode_to_pil(text)
# Convert the Python PIL image to a Cairo surface.
# Notice the conversion to BGRA that Cairo expects
# See http://cairographics.org/pythoncairopil/ and
# http://mail.gnome.org/archives/gtkmm-list/2007-May/msg00111.html
bytearr = array.array('B', self.image.tostring("raw", "BGRA", 0, 1))
height, width = self.image.size
print self.image.size
self.cr_surface = cairo.ImageSurface.create_for_data(bytearr,
cairo.FORMAT_ARGB32,
width, height,
width * 4)
return self.cr_surface
def _encode_to_pil(self, text):
version, self.qrcode_size, self.image = qrencode.encode(text)
self.image = self.image.convert('RGBA')
self._resize()
self._add_border()
return self.image
def _resize(self):
self._set_pixel_size(self.qrcode_size)
print self.pixel_size, self.qrcode_size
self.image = self.image.resize((self.pixel_size * self.qrcode_size,
self.pixel_size * self.qrcode_size),
Image.NEAREST)
def _set_pixel_size(self, barcode_orig_size):
pixel_size = 1
print pixel_size * barcode_orig_size, self.output_size
while (pixel_size * barcode_orig_size < self.output_size):
pixel_size += 1
while ((pixel_size * barcode_orig_size > self.output_size) or \
((pixel_size * barcode_orig_size) % 2 != 0) or \
(pixel_size * barcode_orig_size + 2 * pixel_size > \
self.output_size)):
pixel_size -= 1
# FIXME: it needs to automatically go up to the next size,
# rather than hardcoding it as now
if pixel_size == 0:
self.output_size = QRCodeSize.MEDIUM
self.pixel_size = pixel_size
def _add_border(self):
# Add a border
border_size = (self.output_size - self.image.size[0]) / 2
self.image = ImageOps.expand(self.image, border=border_size,
fill='white')
|