Advertisement
Guest User

Untitled

a guest
Feb 20th, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 3.94 KB | None | 0 0
  1. package qrcode
  2.  
  3. import (
  4. "bytes"
  5. "fmt"
  6. "image"
  7. "image/color"
  8. "image/png"
  9. "math/rand"
  10. "time"
  11.  
  12. qrcode "github.com/skip2/go-qrcode"
  13. )
  14.  
  15. // const (
  16. // QR_CODE_SIZE = 256
  17. // SHRINK_QR_CODE_SIZE = 35
  18. // MARGIN = 29
  19. // MULTIPLE = 6
  20. // )
  21.  
  22. const (
  23. QR_CODE_SIZE = 301
  24. SHRINK_QR_CODE_SIZE = 39
  25. MARGIN = 21
  26. MULTIPLE = 7
  27. )
  28.  
  29. type QRCode struct {
  30. url string
  31. img image.Image
  32. genImg bool
  33. points [QR_CODE_SIZE][QR_CODE_SIZE]int
  34. tmpShrinkPoints [QR_CODE_SIZE][SHRINK_QR_CODE_SIZE]int
  35. shrinkPoints [SHRINK_QR_CODE_SIZE][SHRINK_QR_CODE_SIZE]int
  36. }
  37.  
  38. //NewQRCode 返回二维码结构
  39. func NewQRCode(uri string, genImg bool) *QRCode {
  40. qr := &QRCode{
  41. url: uri,
  42. genImg: genImg,
  43. }
  44.  
  45. qr.genQRCode()
  46.  
  47. return qr
  48. }
  49.  
  50. //genQRCode 生成二维码
  51. func (qr *QRCode) genQRCode() error {
  52. code, err := qrcode.Encode(qr.url, qrcode.Medium, QR_CODE_SIZE)
  53. if err != nil {
  54. return err
  55. }
  56.  
  57. buf := bytes.NewBuffer(code)
  58. img, err := png.Decode(buf)
  59. if err != nil {
  60. return err
  61. }
  62.  
  63. qr.img = img
  64.  
  65. if qr.genImg {
  66. // newPng, _ := os.Create("qrcode.png")
  67. newPng := new(bytes.Buffer)
  68. // defer newPng.Close()
  69. png.Encode(newPng, img)
  70. }
  71.  
  72. return nil
  73. }
  74.  
  75. func (qr *QRCode) SetImage(img image.Image) error {
  76. qr.img = img
  77.  
  78. if qr.genImg {
  79. // newPng, _ := os.Create("qrcode.png")
  80. // defer newPng.Close()
  81. newPng := new(bytes.Buffer)
  82. png.Encode(newPng, img)
  83. }
  84.  
  85. return nil
  86. }
  87.  
  88. //binarization 二维码图片二值化 0-1
  89. func (qr *QRCode) binarization() {
  90. gray := image.NewGray(image.Rect(0, 0, QR_CODE_SIZE, QR_CODE_SIZE))
  91. for x := 0; x < QR_CODE_SIZE; x++ {
  92. for y := 0; y < QR_CODE_SIZE; y++ {
  93. r32, g32, b32, _ := qr.img.At(x, y).RGBA()
  94. r, g, b := int(r32>>8), int(g32>>8), int(b32>>8)
  95. if (r+g+b)/3 > 180 {
  96. qr.points[y][x] = 0
  97. gray.Set(x, y, color.Gray{uint8(255)})
  98. } else {
  99. qr.points[y][x] = 1
  100. gray.Set(x, y, color.Gray{uint8(0)})
  101. }
  102. }
  103. }
  104.  
  105. if qr.genImg {
  106. // newPng, _ := os.Create("qrcode.binarization.png")
  107. // defer newPng.Close()
  108. newPng := new(bytes.Buffer)
  109. png.Encode(newPng, gray)
  110. }
  111. }
  112.  
  113. //shrink 缩小二值化数组
  114. func (qr *QRCode) shrink() {
  115. for x := 0; x < QR_CODE_SIZE; x++ {
  116. cal := 1
  117. for y := MARGIN + 1; y < QR_CODE_SIZE-MARGIN; y += MULTIPLE {
  118. qr.tmpShrinkPoints[x][cal] = qr.points[x][y]
  119. cal++
  120. }
  121. }
  122.  
  123. for y := 1; y < SHRINK_QR_CODE_SIZE-1; y++ {
  124. row := 1
  125. for x := MARGIN + 1; x < QR_CODE_SIZE-MARGIN; x += MULTIPLE {
  126. qr.shrinkPoints[row][y] = qr.tmpShrinkPoints[x][y]
  127. row++
  128. }
  129. }
  130. }
  131.  
  132. //Output 控制台输出二维码
  133. func (qr *QRCode) Output() {
  134. qr.binarization()
  135. qr.shrink()
  136.  
  137. for x := 0; x < SHRINK_QR_CODE_SIZE; x++ {
  138. for y := 0; y < SHRINK_QR_CODE_SIZE; y++ {
  139. if qr.shrinkPoints[x][y] == 1 {
  140. //fmt.Print("\033[40;40m \033[0m")
  141. randColor()
  142. } else {
  143. fmt.Print("\033[47;30m \033[0m")
  144. }
  145. }
  146. fmt.Println()
  147. }
  148. }
  149.  
  150. func randColor() {
  151. cls := []int{41, 42, 43, 44, 45, 46}
  152. rand.Seed(time.Now().UnixNano())
  153. i := rand.Intn(1)
  154. fmt.Printf("\033[40;%dm \033[0m", cls[i])
  155. }
  156.  
  157. //Debug 调试二维码二值化及缩小过程
  158. func (qr *QRCode) Debug() {
  159. qr.binarization()
  160. //qr.shrink()
  161.  
  162. src := new(bytes.Buffer)
  163. for i := 0; i < len(qr.points); i++ {
  164. var line string
  165. for j := 0; j < len(qr.points[i]); j++ {
  166. if qr.points[i][j] == 1 {
  167. line += "1"
  168. } else {
  169. line += "0"
  170. }
  171. }
  172. line += "\n"
  173. src.WriteString(line)
  174. }
  175. // src.Close()
  176.  
  177. tmp := new(bytes.Buffer)
  178. for i := 0; i < len(qr.tmpShrinkPoints); i++ {
  179. var line string
  180. for j := 0; j < len(qr.tmpShrinkPoints[i]); j++ {
  181. if qr.tmpShrinkPoints[i][j] == 1 {
  182. line += "1"
  183. } else {
  184. line += "0"
  185. }
  186. }
  187. line += "\n"
  188. tmp.WriteString(line)
  189. }
  190. // tmp.Close()
  191.  
  192. dst := new(bytes.Buffer)
  193. for i := 0; i < len(qr.shrinkPoints); i++ {
  194. var line string
  195. for j := 0; j < len(qr.shrinkPoints[i]); j++ {
  196. if qr.shrinkPoints[i][j] == 1 {
  197. line += "1"
  198. } else {
  199. line += "0"
  200. }
  201. }
  202. line += "\n"
  203. dst.WriteString(line)
  204. }
  205. // dst.Close()
  206. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement