用python将二维码转换成字符直接输出控制台

用python将二维码转换成字符直接输出控制台

上周,收到了几个有趣的问题邀请,其中一个就是要把二维码直接打印到控制台。

原问题链接:

zhihu.com/question/4925

众所周知,WINDOWS的控制台只能输出字符,所以问题实际上就转变为把二维码转成字符。

还记得网上各种大神都写过的字符画代码么?其实就是类似的思路。

from PIL import Image

加载这个模块就够用了。

实际写的过程,我们发现,每张二维码图片的大小不同,它每个方格的实际像素大小也不同,所以我们需要先计算每个方格的大小,然后每间隔那么大小的位置,取一个像素来计算就可以了。

研究二维码图片,发现左上角的正方形图形里面,再左上角切出来正好就是整幅图有效方块的大小,那么只需要计算这个方块大小即可:

#计算每个方块的大小像素
def get_cell_size(x,y,x2,y2):
    for j in range(x,x2):
        for i in range(y,y2):
            pix = im.getpixel((j,i))
            if pix[:3]==(255,255,255):
                return j - x  #每个黑色格子的像素点大小
def get_cell():
    flag = 0
    for y in range(HEIGHT):
        for x in range(WIDTH):
            pix = im.getpixel((x,y))
            if pix[:3]==(0,0,0) and flag==0: #出现第一个黑色像素
                flag = 1
            if pix[:3]==(255,255,255) and flag ==1 : #出现第一个白色像素(意味着左上角的标记方块横向结束)
                flag = 2
                cell = get_cell_size(x1,x1,x,x)
                return cell

计算完方块大小,就可以每隔这个方块大小,取一个像素点来判断是黑色还是白色:

def get_qrcode(cell):
    height = int(HEIGHT/cell)
    width = int(WIDTH/cell)
    code=''
    for y in range(height):
        for x in range(width):
            pix = im.getpixel((x*cell,y*cell))
            if pix[:3]==(0,0,0):
                code += '▇'
            if pix[:3]==(255,255,255):
                code += ' '
        code += '\n'
    print(code)

输出后发现:每行的间隔有点大,造成无法扫描二维码,调整一下控制台字体:

然后把输出的内容选中反色,就可以扫描了,当然,也可以直接修改布局颜色为白底黑字

(某快餐是否要给点广告费啊,上图二维码是随便网上搜索出来的,并不是广告。)

完整代码如下,抛砖引玉,看看还有没有别的更好的方法来计算:

from PIL import Image
#计算每个方块的大小像素
def get_cell_size(x,y,x2,y2):
    for j in range(x,x2):
        for i in range(y,y2):
            pix = im.getpixel((j,i))
            if pix[:3]==(255,255,255):
                return j - x  #每个黑色格子的像素点大小
def get_cell():
    flag = 0
    for y in range(HEIGHT):
        for x in range(WIDTH):
            pix = im.getpixel((x,y))
            if pix[:3]==(0,0,0) and flag==0: #出现第一个黑色像素
                flag = 1
            if pix[:3]==(255,255,255) and flag ==1 : #出现第一个白色像素(意味着左上角的标记方块横向结束)
                flag = 2
                cell = get_cell_size(x1,x1,x,x)
                return cell
def get_qrcode(cell):
    height = int(HEIGHT/cell)
    width = int(WIDTH/cell)
    code=''
    for y in range(height):
        for x in range(width):
            pix = im.getpixel((x*cell,y*cell))
            if pix[:3]==(0,0,0):
                code += '▇'
            if pix[:3]==(255,255,255):
                code += ' '
        code += '\n'
    print(code)
    input('...')