gitee.com/quant1x/gox@v1.7.6/qrterminal/qrterminal.go (about) 1 package qrterminal 2 3 import ( 4 "io" 5 "strings" 6 7 "rsc.io/qr" 8 ) 9 10 const WHITE = "\033[47m \033[0m" 11 const BLACK = "\033[40m \033[0m" 12 13 // Use ascii blocks to form the QR Code 14 const BLACK_WHITE = "▄" 15 const BLACK_BLACK = " " 16 const WHITE_BLACK = "▀" 17 const WHITE_WHITE = "█" 18 19 // Level - the QR Code's redundancy level 20 const H = qr.H 21 const M = qr.M 22 const L = qr.L 23 24 // default is 4-pixel-wide white quiet zone 25 const QUIET_ZONE = 4 26 27 //Config for generating a barcode 28 type Config struct { 29 Level qr.Level 30 Writer io.Writer 31 HalfBlocks bool 32 BlackChar string 33 BlackWhiteChar string 34 WhiteChar string 35 WhiteBlackChar string 36 QuietZone int 37 } 38 39 func (c *Config) writeFullBlocks(w io.Writer, code *qr.Code) { 40 white := c.WhiteChar 41 black := c.BlackChar 42 43 // Frame the barcode in a 1 pixel border 44 w.Write([]byte(stringRepeat(stringRepeat(white, 45 code.Size+c.QuietZone*2)+"\n", c.QuietZone))) // top border 46 for i := 0; i <= code.Size; i++ { 47 w.Write([]byte(stringRepeat(white, c.QuietZone))) // left border 48 for j := 0; j <= code.Size; j++ { 49 if code.Black(j, i) { 50 w.Write([]byte(black)) 51 } else { 52 w.Write([]byte(white)) 53 } 54 } 55 w.Write([]byte(stringRepeat(white, c.QuietZone-1) + "\n")) // right border 56 } 57 w.Write([]byte(stringRepeat(stringRepeat(white, 58 code.Size+c.QuietZone*2)+"\n", c.QuietZone-1))) // bottom border 59 } 60 61 func (c *Config) writeHalfBlocks(w io.Writer, code *qr.Code) { 62 ww := c.WhiteChar 63 bb := c.BlackChar 64 wb := c.WhiteBlackChar 65 bw := c.BlackWhiteChar 66 // Frame the barcode in a 4 pixel border 67 // top border 68 if c.QuietZone%2 != 0 { 69 w.Write([]byte(stringRepeat(bw, code.Size+c.QuietZone*2) + "\n")) 70 w.Write([]byte(stringRepeat(stringRepeat(ww, 71 code.Size+c.QuietZone*2)+"\n", c.QuietZone/2))) 72 } else { 73 w.Write([]byte(stringRepeat(stringRepeat(ww, 74 code.Size+c.QuietZone*2)+"\n", c.QuietZone/2))) 75 } 76 for i := 0; i <= code.Size; i += 2 { 77 w.Write([]byte(stringRepeat(ww, c.QuietZone))) // left border 78 for j := 0; j <= code.Size; j++ { 79 next_black := false 80 if i+1 < code.Size { 81 next_black = code.Black(j, i+1) 82 } 83 curr_black := code.Black(j, i) 84 if curr_black && next_black { 85 w.Write([]byte(bb)) 86 } else if curr_black && !next_black { 87 w.Write([]byte(bw)) 88 } else if !curr_black && !next_black { 89 w.Write([]byte(ww)) 90 } else { 91 w.Write([]byte(wb)) 92 } 93 } 94 w.Write([]byte(stringRepeat(ww, c.QuietZone-1) + "\n")) // right border 95 } 96 // bottom border 97 if c.QuietZone%2 == 0 { 98 w.Write([]byte(stringRepeat(stringRepeat(ww, 99 code.Size+c.QuietZone*2)+"\n", c.QuietZone/2-1))) 100 w.Write([]byte(stringRepeat(wb, code.Size+c.QuietZone*2) + "\n")) 101 } else { 102 w.Write([]byte(stringRepeat(stringRepeat(ww, 103 code.Size+c.QuietZone*2)+"\n", c.QuietZone/2))) 104 } 105 } 106 107 func stringRepeat(s string, count int) string { 108 if count <= 0 { 109 return "" 110 } 111 return strings.Repeat(s, count) 112 } 113 114 // GenerateWithConfig expects a string to encode and a config 115 func GenerateWithConfig(text string, config Config) { 116 if config.QuietZone < 1 { 117 config.QuietZone = 1 // at least 1-pixel-wide white quiet zone 118 } 119 w := config.Writer 120 code, _ := qr.Encode(text, config.Level) 121 if config.HalfBlocks { 122 config.writeHalfBlocks(w, code) 123 } else { 124 config.writeFullBlocks(w, code) 125 } 126 } 127 128 // Generate a QR Code and write it out to io.Writer 129 func Generate(text string, l qr.Level, w io.Writer) { 130 config := Config{ 131 Level: l, 132 Writer: w, 133 BlackChar: BLACK, 134 WhiteChar: WHITE, 135 QuietZone: QUIET_ZONE, 136 } 137 GenerateWithConfig(text, config) 138 } 139 140 // Generate a QR Code with half blocks and write it out to io.Writer 141 func GenerateHalfBlock(text string, l qr.Level, w io.Writer) { 142 config := Config{ 143 Level: l, 144 Writer: w, 145 HalfBlocks: true, 146 BlackChar: BLACK_BLACK, 147 WhiteBlackChar: WHITE_BLACK, 148 WhiteChar: WHITE_WHITE, 149 BlackWhiteChar: BLACK_WHITE, 150 QuietZone: QUIET_ZONE, 151 } 152 GenerateWithConfig(text, config) 153 }