SHARE
TWEET

Untitled

a guest Feb 20th, 2019 50 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  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. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top