qrcode.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458
  1. // go-qrcode
  2. // Copyright 2014 Tom Harwood
  3. /*
  4. Package qrcode implements a QR Code encoder.
  5. A QR Code is a matrix (two-dimensional) barcode. Arbitrary content may be
  6. encoded.
  7. A QR Code contains error recovery information to aid reading damaged or
  8. obscured codes. There are four levels of error recovery: qrcode.{Low, Medium,
  9. High, Highest}. QR Codes with a higher recovery level are more robust to damage,
  10. at the cost of being physically larger.
  11. Two functions cover most use cases:
  12. - Create a PNG image:
  13. var png []byte
  14. png, err := qrcode.Encode("https://example.org", qrcode.Medium, 256)
  15. - Create a PNG image and write to a file:
  16. err := qrcode.WriteFile("https://example.org", qrcode.Medium, 256, "qr.png")
  17. Both examples use the qrcode.Medium error Recovery Level and create a 256x256
  18. pixel, black on white QR Code.
  19. The maximum capacity of a QR Code varies according to the content encoded and
  20. the error recovery level. The maximum capacity is 2,953 bytes, 4,296
  21. alphanumeric characters, 7,089 numeric digits, or a combination of these.
  22. This package implements a subset of QR Code 2005, as defined in ISO/IEC
  23. 18004:2006.
  24. */
  25. package qrcode
  26. import (
  27. "bytes"
  28. "errors"
  29. "image"
  30. "image/color"
  31. "image/png"
  32. "io/ioutil"
  33. "log"
  34. "os"
  35. bitset "code.google.com/p/go-qrcode/bitset"
  36. reedsolomon "code.google.com/p/go-qrcode/reedsolomon"
  37. )
  38. // Encode a QR Code and return a raw PNG image.
  39. //
  40. // size is both the image width and height in pixels. If size is too small then
  41. // a larger image is silently returned.
  42. //
  43. // To serve over HTTP, remember to send a Content-Type: image/png header.
  44. func Encode(content string, level RecoveryLevel, size int) ([]byte, error) {
  45. var q *QRCode
  46. q, err := New(content, level)
  47. if err != nil {
  48. return nil, err
  49. }
  50. return q.PNG(size)
  51. }
  52. // WriteFile encodes, then writes a QR Code to the given filename in PNG format.
  53. //
  54. // size is both the width and height in pixels. If size is too small then a
  55. // larger image is silently written.
  56. func WriteFile(content string, level RecoveryLevel, size int, filename string) error {
  57. var q *QRCode
  58. q, err := New(content, level)
  59. if err != nil {
  60. return err
  61. }
  62. return q.WriteFile(size, filename)
  63. }
  64. // A QRCode represents a valid encoded QRCode.
  65. type QRCode struct {
  66. // Original content encoded.
  67. Content string
  68. // QR Code type.
  69. Level RecoveryLevel
  70. VersionNumber int
  71. // User settable drawing options.
  72. ForegroundColor color.Color
  73. BackgroundColor color.Color
  74. encoder *dataEncoder
  75. version qrCodeVersion
  76. data *bitset.Bitset
  77. symbol *symbol
  78. mask int
  79. }
  80. // New constructs a QRCode.
  81. //
  82. // var q *qrcode.QRCode
  83. // q, err := qrcode.New("my content", qrcode.Medium)
  84. //
  85. // An error occurs if the content is too long.
  86. func New(content string, level RecoveryLevel) (*QRCode, error) {
  87. encoders := []dataEncoderType{dataEncoderType1To9, dataEncoderType10To26,
  88. dataEncoderType27To40}
  89. var encoder *dataEncoder
  90. var encoded *bitset.Bitset
  91. var chosenVersion *qrCodeVersion
  92. var err error
  93. for _, t := range encoders {
  94. encoder = newDataEncoder(t)
  95. encoded, err = encoder.encode([]byte(content))
  96. if err != nil {
  97. continue
  98. }
  99. chosenVersion = chooseQRCodeVersion(level, encoder, encoded.Len())
  100. if chosenVersion != nil {
  101. break
  102. }
  103. }
  104. if err != nil {
  105. return nil, err
  106. } else if chosenVersion == nil {
  107. return nil, errors.New("content too long to encode")
  108. }
  109. q := &QRCode{
  110. Content: content,
  111. Level: level,
  112. VersionNumber: chosenVersion.version,
  113. ForegroundColor: color.Black,
  114. BackgroundColor: color.White,
  115. encoder: encoder,
  116. data: encoded,
  117. version: *chosenVersion,
  118. }
  119. q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len()))
  120. return q, nil
  121. }
  122. func newWithForcedVersion(content string, version int, level RecoveryLevel) (*QRCode, error) {
  123. var encoder *dataEncoder
  124. switch {
  125. case version >= 1 && version <= 9:
  126. encoder = newDataEncoder(dataEncoderType1To9)
  127. case version >= 10 && version <= 26:
  128. encoder = newDataEncoder(dataEncoderType10To26)
  129. case version >= 27 && version <= 40:
  130. encoder = newDataEncoder(dataEncoderType27To40)
  131. default:
  132. log.Fatalf("Invalid version %d (expected 1-40 inclusive)", version)
  133. }
  134. var encoded *bitset.Bitset
  135. encoded, err := encoder.encode([]byte(content))
  136. if err != nil {
  137. return nil, err
  138. }
  139. chosenVersion := getQRCodeVersion(level, version)
  140. if chosenVersion == nil {
  141. return nil, errors.New("cannot find QR Code version")
  142. }
  143. q := &QRCode{
  144. Content: content,
  145. Level: level,
  146. VersionNumber: chosenVersion.version,
  147. ForegroundColor: color.Black,
  148. BackgroundColor: color.White,
  149. encoder: encoder,
  150. data: encoded,
  151. version: *chosenVersion,
  152. }
  153. q.encode(chosenVersion.numTerminatorBitsRequired(encoded.Len()))
  154. return q, nil
  155. }
  156. // Bitmap returns the QR Code as a 2D array of 1-bit pixels.
  157. //
  158. // bitmap[y][x] is true if the pixel at (x, y) is set.
  159. //
  160. // The bitmap includes the required "quiet zone" around the QR Code to aid
  161. // decoding.
  162. func (q *QRCode) Bitmap() [][]bool {
  163. return q.symbol.bitmap()
  164. }
  165. // Image returns the QR Code as an image.Image.
  166. //
  167. // size is both the width and height in pixels.
  168. func (q *QRCode) Image(size int) image.Image {
  169. // Minimum pixels (both width and height) required.
  170. realSize := q.symbol.size
  171. // Actual pixels available to draw the symbol. Automatically increase the
  172. // image size if it's not large enough.
  173. if size < realSize {
  174. size = realSize
  175. }
  176. // Size of each module drawn.
  177. pixelsPerModule := size / realSize
  178. // Center the symbol within the image.
  179. offset := (size - realSize*pixelsPerModule) / 2
  180. rect := image.Rectangle{Min: image.Point{0, 0}, Max: image.Point{size, size}}
  181. img := image.NewRGBA(rect)
  182. for i := 0; i < size; i++ {
  183. for j := 0; j < size; j++ {
  184. img.Set(i, j, q.BackgroundColor)
  185. }
  186. }
  187. bitmap := q.symbol.bitmap()
  188. for y, row := range bitmap {
  189. for x, v := range row {
  190. if v {
  191. startX := x*pixelsPerModule + offset
  192. startY := y*pixelsPerModule + offset
  193. for i := startX; i < startX+pixelsPerModule; i++ {
  194. for j := startY; j < startY+pixelsPerModule; j++ {
  195. img.Set(i, j, q.ForegroundColor)
  196. }
  197. }
  198. }
  199. }
  200. }
  201. return img
  202. }
  203. // PNG returns the QR Code as a PNG image.
  204. //
  205. // size is both the image width and height in pixels. If size is too small then
  206. // a larger image is silently returned.
  207. func (q *QRCode) PNG(size int) ([]byte, error) {
  208. img := q.Image(size)
  209. var b bytes.Buffer
  210. err := png.Encode(&b, img)
  211. if err != nil {
  212. return nil, err
  213. }
  214. return b.Bytes(), nil
  215. }
  216. // WriteFile writes the QR Code as a PNG image to the specified file.
  217. //
  218. // size is both the image width and height in pixels. If size is too small then
  219. // a larger image is silently written.
  220. func (q *QRCode) WriteFile(size int, filename string) error {
  221. var png []byte
  222. png, err := q.PNG(size)
  223. if err != nil {
  224. return err
  225. }
  226. return ioutil.WriteFile(filename, png, os.FileMode(0644))
  227. }
  228. // encode completes the steps required to encode the QR Code. These include
  229. // adding the terminator bits and padding, splitting the data into blocks and
  230. // applying the error correction, and selecting the best data mask.
  231. func (q *QRCode) encode(numTerminatorBits int) {
  232. q.addTerminatorBits(numTerminatorBits)
  233. q.addPadding()
  234. encoded := q.encodeBlocks()
  235. const numMasks int = 8
  236. penalty := 0
  237. for mask := 0; mask < numMasks; mask++ {
  238. var s *symbol
  239. var err error
  240. s, err = buildRegularSymbol(q.version, mask, encoded)
  241. if err != nil {
  242. log.Panic(err.Error())
  243. }
  244. p := s.penaltyScore()
  245. //log.Printf("mask=%d p=%3d p1=%3d p2=%3d p3=%3d p4=%d\n", mask, p, s.penalty1(), s.penalty2(), s.penalty3(), s.penalty4())
  246. if q.symbol == nil || p < penalty {
  247. q.symbol = s
  248. q.mask = mask
  249. penalty = p
  250. }
  251. }
  252. }
  253. // addTerminatorBits adds final terminator bits to the encoded data.
  254. //
  255. // The number of terminator bits required is determined when the QR Code version
  256. // is chosen (which itself depends on the length of the data encoded). The
  257. // terminator bits are thus added after the QR Code version
  258. // is chosen, rather than at the data encoding stage.
  259. func (q *QRCode) addTerminatorBits(numTerminatorBits int) {
  260. q.data.AppendNumBools(numTerminatorBits, false)
  261. }
  262. // encodeBlocks takes the completed (terminated & padded) encoded data, splits
  263. // the data into blocks (as specified by the QR Code version), applies error
  264. // correction to each block, then interleaves the blocks together.
  265. //
  266. // The QR Code's final data sequence is returned.
  267. func (q *QRCode) encodeBlocks() *bitset.Bitset {
  268. // Split into blocks.
  269. type dataBlock struct {
  270. data *bitset.Bitset
  271. ecStartOffset int
  272. }
  273. block := make([]dataBlock, q.version.numBlocks())
  274. start := 0
  275. end := 0
  276. blockID := 0
  277. for _, b := range q.version.block {
  278. for j := 0; j < b.numBlocks; j++ {
  279. start = end
  280. end = start + b.numDataCodewords*8
  281. // Apply error correction to each block.
  282. numErrorCodewords := b.numCodewords - b.numDataCodewords
  283. block[blockID].data = reedsolomon.Encode(q.data.Substr(start, end), numErrorCodewords)
  284. block[blockID].ecStartOffset = end - start
  285. blockID++
  286. }
  287. }
  288. // Interleave the blocks.
  289. // A single block doesn't need interleaving.
  290. if len(block) == 1 {
  291. return block[0].data
  292. }
  293. result := bitset.New()
  294. // Combine data blocks.
  295. working := true
  296. for i := 0; working; i += 8 {
  297. working = false
  298. for j, b := range block {
  299. if i >= block[j].ecStartOffset {
  300. continue
  301. }
  302. result.Append(b.data.Substr(i, i+8))
  303. working = true
  304. }
  305. }
  306. // Combine error correction blocks.
  307. working = true
  308. for i := 0; working; i += 8 {
  309. working = false
  310. for j, b := range block {
  311. offset := i + block[j].ecStartOffset
  312. if offset >= block[j].data.Len() {
  313. continue
  314. }
  315. result.Append(b.data.Substr(offset, offset+8))
  316. working = true
  317. }
  318. }
  319. // Append remainder bits.
  320. result.AppendNumBools(q.version.numRemainderBits, false)
  321. return result
  322. }
  323. // max returns the maximum of a and b.
  324. func max(a int, b int) int {
  325. if a > b {
  326. return a
  327. }
  328. return b
  329. }
  330. // addPadding pads the encoded data upto the full length required.
  331. func (q *QRCode) addPadding() {
  332. numDataBits := q.version.numDataBits()
  333. if q.data.Len() == numDataBits {
  334. return
  335. }
  336. // Pad to the nearest codeword boundary.
  337. q.data.AppendNumBools(q.version.numBitsToPadToCodeword(q.data.Len()), false)
  338. // Pad codewords 0b11101100 and 0b00010001.
  339. padding := [2]*bitset.Bitset{
  340. bitset.New(true, true, true, false, true, true, false, false),
  341. bitset.New(false, false, false, true, false, false, false, true),
  342. }
  343. // Insert pad codewords alternately.
  344. i := 0
  345. for numDataBits-q.data.Len() >= 8 {
  346. q.data.Append(padding[i])
  347. i = 1 - i // Alternate between 0 and 1.
  348. }
  349. if q.data.Len() != numDataBits {
  350. log.Panicf("BUG: got len %d, expected %d", q.data.Len(), numDataBits)
  351. }
  352. }