-
Notifications
You must be signed in to change notification settings - Fork 0
/
qr.go
87 lines (71 loc) · 1.88 KB
/
qr.go
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
package qrcode
import (
"image"
"image/color"
"github.com/cristalhq/qrcode/internal/coding"
)
// A Level denotes a QR error correction level.
// From least to most tolerant of errors, they are L, M, Q, H.
type Level int
const (
L Level = 0 // 20% redundant
M Level = 1 // 38% redundant
Q Level = 2 // 55% redundant
H Level = 3 // 65% redundant
)
// Encode returns an encoding of text at the given error correction level.
func Encode(text string, level Level) (*Code, error) {
return EncodeInto(nil, text, level)
}
func EncodeInto(bitmap []byte, text string, level Level) (*Code, error) {
cc, err := coding.Encode(bitmap, text, coding.Level(level))
if err != nil {
return nil, err
}
code := &Code{
Bitmap: cc.Bitmap,
Size: cc.Size,
Stride: cc.Stride,
Scale: 8,
}
return code, nil
}
// A Code is a square pixel grid.
// It implements image.Image and direct PNG encoding.
type Code struct {
Bitmap []byte // 1 is black, 0 is white
Size int // number of pixels on a side
Stride int // number of bytes per row
Scale int // number of image pixels per QR pixel
}
// IsBlack returns true if the pixel at (x,y) is black.
func (c *Code) IsBlack(x, y int) bool {
idx := y*c.Stride + x/8
mask := byte(1 << uint(7-x&7))
return 0 <= x && x < c.Size &&
0 <= y && y < c.Size &&
c.Bitmap[idx]&mask != 0
}
// Image returns an Image displaying the code.
func (c *Code) Image() image.Image {
return &codeImage{c}
}
// codeImage implements image.Image.
type codeImage struct{ *Code }
func (c *codeImage) Bounds() image.Rectangle {
d := (c.Size + 8) * c.Scale
return image.Rect(0, 0, d, d)
}
func (c *codeImage) At(x, y int) color.Color {
if c.IsBlack(x/c.Scale-4, y/c.Scale-4) {
return blackColor
}
return whiteColor
}
func (c *codeImage) ColorModel() color.Model {
return color.GrayModel
}
var (
blackColor = color.Gray{Y: 0x00}
whiteColor = color.Gray{Y: 0xFF}
)