Terminal展示二维码

1,335 阅读2分钟

最近再看二维码的实现,因为需要写一些Demo,为了方便调试,能直接 terminal 中展示二维码就方便了,于是乎,看了看qrcode-terminal实现,里面涉及两种方式:

1. 空格&颜色

在 termnial 中可以通过设置 \033[{色值}m设置颜色,如果需要重置颜色,可以再次通过\033[0m重置颜色。 \033是 ESC 的keyCode的 8 进制表现方式。

二维码的可以理解其实就是一个二维数组,里面包含标志位,标识是黑块或者白块, 故可以使用以下函数打印二维码:

function print(modules) {
  const black = '\033[40m  \033[0m'
  const white = '\033[47m  \033[0m'

  const rowLength = modules[0].length
  const border = Array(rowLength + 2)
    .fill(white)
    .join('')
  let output = border + '\n'

  modules.forEach((r) => {
    output += white
    output += r.map((i) => (i ? black : white)).join('')
    output += white + '\n'
  })
  output += border
  console.log(output)
}
// 使用方式
print([
  [1, 0, 1, 0],
  [0, 1, 0, 1],
  [1, 0, 1, 0],
  [0, 1, 0, 1],
])

2.使用unicode形式

利用空格可以比较简单的实现色块的展示,但是如果想要控制色块的大小,通过方式1是无法实现的,而且terminal也没有提供修改色块宽高的api,但可以通过unicode实现大小的减半,思路是利用三个不同的unicode,全白、半白半黑、半黑半白、全黑,对应的unicode为:

{
    WHITE_ALL: '\u2588',
    WHITE_BLACK: '\u2580',
    BLACK_WHITE: '\u2584',
    BLACK_ALL: ' ',
}

function printByUnicode(moduleData) {
  const WHITE_ALL = '\u2588'
  const WHITE_BLACK = '\u2580'
  const BLACK_WHITE = '\u2584'
  const BLACK_ALL = ' '
  const rowLength = moduleData[0].length

  const borderTop = Array(rowLength + 2)
    .fill(BLACK_WHITE)
    .join('')
  const borderBottom = Array(rowLength + 2)
    .fill(WHITE_BLACK)
    .join('')

  let output = borderTop + '\n'
  for (let row = 0; row < rowLength; row += 2) {
    output += WHITE_ALL

    for (let col = 0; col < rowLength; col++) {
      if (!moduleData[row][col] && !moduleData[row + 1][col]) {
        output += WHITE_ALL
      } else if (!moduleData[row][col] && moduleData[row + 1][col]) {
        output += WHITE_BLACK
      } else if (moduleData[row][col] && !moduleData[row + 1][col]) {
        output += BLACK_WHITE
      } else {
        output += BLACK_ALL
      }
    }

    output += WHITE_ALL + '\n'
  }
  output += borderBottom
  console.log(output)
}

用同一个数据:

[
  [1, 0, 1, 0],
  [0, 1, 0, 1],
  [1, 0, 1, 0],
  [0, 1, 0, 1],
]

对比两种方式:

其中小的就是unicode的,大的就是空格&色值。