Python qrcode 生成个性的透明二维码

需求生成这样的批量生成这样的二维码,用MyQR生成的不是很满意,没有去细研究MyQR,所以用qrcode 和PIL生成。(欢迎批评)

在这里插入图片描述

# _*_ coding:utf-8 _*_

'''
创建时间:2020-12-07
文件说明:生成个性的带背景图的二维码
'''

import os
import sys
import qrcode
from PIL import Image, ImageDraw

Base_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.append(Base_DIR)

whiteRGB = (255,255,255,255)  # 白色RGB值
blackRGB = (0,0,0,255)        # 黑色RGB值

class GenerateQRCode(object):
    '''
        生成透明带背景图的二维码
        返回图片
    '''
    # 初始化参数
    def __init__(self, background_map, version=5, error_correction=qrcode.ERROR_CORRECT_H, box_size=8, border=2):
        self.version = version                        # 版本信息
        self.error_correction = error_correction      # 容错率
        self.box_size = box_size                      # 二维码位置确定的点数
        self.border = border                          # 边框
        self.background_map = background_map
        
    # 白色背景透明设置
    def __transparent_back(self,image):
        img = image.convert('RGBA')
        L, H = img.size
        color_0 = whiteRGB   #要替换的颜色
        for h in range(H):
            for l in range(L):
                dot = (l,h)
                color_1 = img.getpixel(dot)
                if color_1 == color_0:
                    color_1 = color_1[:-1] + (0,)
                    img.putpixel(dot,color_1)
        return img
    
    # 计算二维码黑点白点位置
    def __position(self,coordinate):
        Tlist = list()
        Flist = list()
        rnum = int(self.box_size/(self.box_size/2))
        clen = len(coordinate)
        numy = 0
        for y in coordinate:
            if self.border - 1 < numy < self.box_size + self.border:
                numx = 0
                for x in y:
                    if  self.box_size + self.border <= numx < clen - (self.box_size + self.border): 
                        if x == True: 
                            # 计算出坐标位置
                            wx = int(numx*self.box_size) + rnum
                            hy = int(numy*self.box_size) + rnum
                            Tlist.append((wx,hy))
                        elif x == False:
                            wx = int(numx*self.box_size) + rnum
                            hy = int(numy*self.box_size) + rnum
                            Flist.append((wx,hy))
                    numx += 1
            elif self.box_size + self.border <= numy < clen - (self.box_size + self.border):
                numx = 0
                for x in y:
                    if self.border - 1 < numx < clen - self.border:
                        if x == True:
                            wx = int(numx*self.box_size) + rnum
                            hy = int(numy*self.box_size) + rnum
                            Tlist.append((wx,hy))
                        else:
                            wx = int(numx*self.box_size) + rnum
                            hy = int(numy*self.box_size) + rnum
                            Flist.append((wx,hy))
                    numx += 1
            elif clen - (self.box_size + self.border) <= numy < clen - self.border:
                numx = 0
                for x in y:
                    if  self.box_size + self.border <= numx < clen - self.border : 
                        if x == True:
                            wx = int(numx*self.box_size) + rnum
                            hy = int(numy*self.box_size) + rnum
                            Tlist.append((wx,hy))
                        elif x == False:
                            wx = int(numx*self.box_size) + rnum
                            hy = int(numy*self.box_size) + rnum
                            Flist.append((wx,hy))
                    numx += 1
            numy += 1
        return Tlist,Flist
        
    # 生成二维码
    def Qrcode(self, txt):
        qr = qrcode.QRCode(
            version = self.version,
            error_correction = self.error_correction,
            box_size = self.box_size,
            border = self.border,
        )
        qr.add_data(txt)
        qr.make(fit=True)
        # 获取二维码矩阵
        coordinate = qr.get_matrix()
        # 获取生成的二维码大小
        qrimg = qr.make_image()
        qrimg = self.__transparent_back(qrimg)
        w, h = qrimg.size
        # 打开背景图
        b_map = Image.open(self.background_map)
        # 设置背景图大小
        b_map_image = b_map.resize((w, h), Image.ANTIALIAS)
        # 获取黑点和白点的列表
        (Tlist, Flist) = self.__position(coordinate)
        '''
        1、把需要缩小的黑色块变成白色
        2、画出黑色的小块
        3、把图片白色透明
        4、二维码图和背景图合并
        5、画出白色的小方块
        '''

        rnum = int(self.box_size/(self.box_size/2))
        for n in Tlist:
            for m in range(self.box_size + 1):
                for m1 in range(self.box_size + 1):
                    qrimg.putpixel((n[0]-rnum + m1, n[1]-rnum + m),(255,255,255,255))
            for p in range(rnum + 2):
                for p1 in range(rnum + 2):
                    qrimg.putpixel((n[0] + p1, n[1]+p),(0,0,0,255))
        
        image = self.__transparent_back(qrimg)
        for n1 in Flist:
            for p in range(rnum + 2):
                for p1 in range(rnum + 2):
                    image.putpixel((n1[0] + p1, n1[1]+p),(255,255,255,255))
        # 保存图片
        b_map_image.paste(image, (0, 0), image)
        save_file = Base_DIR + '/static/code.png'
        b_map_image.save(save_file, quality=100)

if __name__ == "__main__":
    icon_path = Base_DIR + '/static/logo.jpg'
    gqrc = GenerateQRCode(background_map=icon_path)
    gqrc.Qrcode("http://wwww.baidu.com")

猜你喜欢

转载自blog.csdn.net/qq_40430818/article/details/110851512