从零开始用Python生成码:自定义样式与Logo嵌入

二维码和条形码已成为现代信息传递的重要工具,从支付扫码到产品溯源,从活动签到到数据存储,这些黑白方块和线条背后藏着巨大的应用潜力。但默认生成的码往往千篇一律,如何让它们既实用又美观?本文将带你用Python从零实现码生成,并掌握自定义样式和嵌入Logo的核心技巧。


一、基础准备:选择合适的Python库

生成码的核心是选择可靠的库。Python生态中有多个优秀选项:

1.1 二维码生成:qrcode库

qrcode是Python最流行的二维码生成库,支持多种纠错级别和尺寸调整。安装只需:

css 复制代码
pip install qrcode[pil]

[pil]表示同时安装Pillow图像处理库,用于后续样式定制)

1.2 条形码生成:python-barcode库

对于条形码(如EAN-13、UPC-A等),python-barcode是专业选择:

复制代码
pip install python-barcode

它支持17种标准条形码格式,输出为SVG或PIL图像。

1.3 图像处理:Pillow库

无论二维码还是条形码,最终都需要与Logo或背景融合,Pillow(PIL)是Python图像处理的标配:

复制代码
pip install pillow

二、基础码生成:从黑白方块开始

2.1 生成简单二维码

qrcode生成基础二维码只需3行代码:

ini 复制代码
import qrcode

# 创建二维码实例
qr = qrcode.QRCode(
    version=1,  # 控制二维码大小(1-40)
    error_correction=qrcode.constants.ERROR_CORRECT_L,  # 纠错级别
    box_size=10,  # 每个"点"的像素数
    border=4,  # 边框宽度(单位:box_size)
)

# 添加数据
qr.add_data("https://example.com")
qr.make(fit=True)  # 自动调整尺寸

# 生成图像并保存
img = qr.make_image(fill_color="black", back_color="white")
img.save("basic_qr.png")

运行后会生成一个黑白分明的二维码图片。

2.2 生成标准条形码

以EAN-13格式为例:

ini 复制代码
import barcode
from barcode.writer import ImageWriter

# 创建条形码生成器
ean = barcode.get_barcode_class('ean13')
code = ean("5901234123457", writer=ImageWriter())  # EAN-13需要12位数字

# 保存为PNG文件
filename = code.save("basic_barcode")  # 自动添加.png后缀

生成的条形码会保存在当前目录。


三、进阶技巧:自定义码的样式

3.1 二维码颜色定制

通过fill_colorback_color参数可轻松改变颜色:

ini 复制代码
img = qr.make_image(
    fill_color="#FF5733",  # 二维码颜色(支持十六进制)
    back_color="#33FF57"   # 背景颜色
)

3.2 二维码形状变形

默认二维码是正方形,但可通过module_shape参数改为圆形或其他形状(需qrcode 7.0+版本):

ini 复制代码
from qrcode.image.styledpil import StyledPilImage
from qrcode.image.styles.moduledrawers import RoundedModuleDrawer

qr = qrcode.QRCode()
qr.add_data("https://example.com")
img = qr.make_image(
    image_factory=StyledPilImage,
    module_drawer=RoundedModuleDrawer(),  # 使用圆形模块
    eye_drawer=RoundedModuleDrawer()     # 定位图案也圆形
)
img.save("rounded_qr.png")

3.3 条形码样式调整

python-barcode通过writer参数控制样式:

python 复制代码
from barcode.writer import ImageWriter

options = {
    "module_width": 0.2,          # 单个条的宽度(mm)
    "module_height": 15.0,        # 条形码高度(mm)
    "font_size": 10,              # 底部数字字体大小
    "text_distance": 5.0,         # 数字与条形码距离(mm)
    "center_text": True           # 数字居中
}

ean = barcode.get_barcode_class('ean13')
code = ean("5901234123457", writer=ImageWriter(), writer_options=options)
code.save("styled_barcode")

关键步骤:

  1. 生成基础二维码
  2. 用Pillow打开二维码图像
  3. 打开Logo图像并调整大小
  4. 将Logo粘贴到二维码中心
  5. 保存最终图像

完整代码:

ini 复制代码
import qrcode
from PIL import Image

def generate_qr_with_logo(data, logo_path, output_path, qr_size=400, logo_size=80):
    # 生成二维码
    qr = qrcode.QRCode(
        version=1,
        error_correction=qrcode.constants.ERROR_CORRECT_H,  # 高纠错级别(30%容错)
        box_size=10,
        border=4
    )
    qr.add_data(data)
    qr.make(fit=True)
    
    # 创建二维码图像
    img_qr = qr.make_image(fill_color="black", back_color="white").convert("RGB")
    img_qr = img_qr.resize((qr_size, qr_size))  # 调整二维码大小
    
    # 打开并调整Logo
    try:
        img_logo = Image.open(logo_path).convert("RGBA")
        img_logo = img_logo.resize((logo_size, logo_size))
        
        # 计算Logo位置(居中)
        position = ((qr_size - logo_size) // 2, (qr_size - logo_size) // 2)
        
        # 创建带透明通道的二维码背景
        img_qr_with_alpha = Image.new("RGBA", img_qr.size, (255, 255, 255, 0))
        img_qr_with_alpha.paste(img_qr, (0, 0))
        
        # 确保Logo区域可覆盖(高纠错级别保障可读性)
        img_qr_with_alpha.paste(img_logo, position, img_logo)
        
        # 转换为RGB模式保存
        result = img_qr_with_alpha.convert("RGB")
        result.save(output_path)
        print(f"二维码已保存至: {output_path}")
    except Exception as e:
        print(f"处理Logo时出错: {e}")
        img_qr.save(output_path)  # 出错时保存无Logo版本

# 使用示例
generate_qr_with_logo(
    data="https://example.com",
    logo_path="logo.png",
    output_path="qr_with_logo.png",
    qr_size=600,
    logo_size=120
)

4.2 条形码嵌入Logo(谨慎使用)

条形码对Logo嵌入更敏感,建议:

  1. 将Logo放在条形码上方/下方空白处
  2. 避免遮挡条形码本身
  3. 使用高对比度颜色

示例代码:

python 复制代码
from barcode.writer import ImageWriter
from PIL import Image, ImageDraw, ImageFont

def generate_barcode_with_logo(data, logo_path, output_path):
    # 生成条形码
    ean = barcode.get_barcode_class('ean13')
    options = {
        "module_width": 0.3,
        "module_height": 30.0,
        "font_size": 12,
        "text_distance": 5.0
    }
    code = ean(data, writer=ImageWriter(), writer_options=options)
    filename = code.save("temp_barcode")  # 临时保存
    
    # 打开条形码和Logo
    img_barcode = Image.open("temp_barcode.png")
    try:
        img_logo = Image.open(logo_path).convert("RGBA")
        img_logo = img_logo.resize((100, 50))  # 调整Logo大小
        
        # 创建新图像(条形码高度+Logo高度+间距)
        new_height = img_barcode.height + img_logo.height + 20
        new_img = Image.new("RGB", (img_barcode.width, new_height), "white")
        
        # 粘贴条形码和Logo
        new_img.paste(img_barcode, (0, 0))
        new_img.paste(img_logo, ((img_barcode.width - img_logo.width) // 2, img_barcode.height + 10), img_logo)
        
        new_img.save(output_path)
        print(f"条形码已保存至: {output_path}")
    except Exception as e:
        print(f"处理Logo时出错: {e}")
        img_barcode.save(output_path)  # 出错时保存无Logo版本
    finally:
        import os
        if os.path.exists("temp_barcode.png"):
            os.remove("temp_barcode.png")

# 使用示例
generate_barcode_with_logo(
    data="5901234123457",
    logo_path="logo.png",
    output_path="barcode_with_logo.png"
)

五、实战案例:制作活动签到二维码

假设需要为一场活动生成带Logo的签到二维码,要求:

  • 包含活动专属URL
  • 使用活动主题色
  • 嵌入活动Logo
  • 尺寸适合打印(A4纸每页4个)

完整解决方案:

ini 复制代码
import qrcode
from PIL import Image
import os

def generate_event_qr(event_url, logo_path, output_folder, count=100):
    # 确保输出目录存在
    os.makedirs(output_folder, exist_ok=True)
    
    # 二维码配置
    qr_config = {
        "version": 5,  # 较大尺寸以容纳更多数据
        "error_correction": qrcode.constants.ERROR_CORRECT_H,
        "box_size": 8,
        "border": 2
    }
    
    # 颜色配置(活动主题色)
    fill_color = (0, 102, 204)  # 蓝色
    back_color = (255, 255, 255)  # 白色
    
    # Logo配置
    logo_size = 80  # 像素
    
    for i in range(1, count + 1):
        # 生成带编号的URL(假设URL格式为 https://example.com/checkin?id=XXX)
        current_url = f"{event_url}?id={i:03d}"
        
        # 生成二维码
        qr = qrcode.QRCode(**qr_config)
        qr.add_data(current_url)
        qr.make(fit=True)
        
        # 创建图像
        img_qr = qr.make_image(fill_color=fill_color, back_color=back_color).convert("RGB")
        img_qr = img_qr.resize((400, 400))  # 最终尺寸
        
        # 处理Logo
        try:
            img_logo = Image.open(logo_path).convert("RGBA")
            img_logo = img_logo.resize((logo_size, logo_size))
            
            # 创建带透明通道的二维码
            img_qr_with_alpha = Image.new("RGBA", img_qr.size, (255, 255, 255, 0))
            img_qr_with_alpha.paste(img_qr, (0, 0))
            
            # 粘贴Logo(居中)
            position = ((400 - logo_size) // 2, (400 - logo_size) // 2)
            img_qr_with_alpha.paste(img_logo, position, img_logo)
            
            # 转换为RGB
            final_img = img_qr_with_alpha.convert("RGB")
            
            # 添加编号文字(底部居中)
            draw = ImageDraw.Draw(final_img)
            font = ImageFont.truetype("arial.ttf", 24)  # 使用系统字体
            text = f"签到码 #{i:03d}"
            text_width, text_height = draw.textsize(text, font=font)
            draw.text(
                ((400 - text_width) // 2, 370),
                text,
                fill="black",
                font=font
            )
            
            # 保存
            output_path = os.path.join(output_folder, f"qr_{i:03d}.png")
            final_img.save(output_path)
            print(f"已生成: {output_path}")
        except Exception as e:
            print(f"生成签到码 {i} 时出错: {e}")
            # 保存无Logo版本
            img_qr.save(os.path.join(output_folder, f"qr_{i:03d}_no_logo.png"))

# 使用示例
generate_event_qr(
    event_url="https://example.com/checkin",
    logo_path="event_logo.png",
    output_folder="event_qrcodes",
    count=20
)

六、常见问题Q&A

Q1:生成的二维码扫描不出来怎么办?

A:检查以下原因:

  1. 纠错级别设置过低(建议使用ERROR_CORRECT_H
  2. Logo过大遮挡了关键定位图案(确保Logo不超过二维码面积的30%)
  3. 颜色对比度不足(黑白对比最可靠,彩色需确保明暗差异明显)
  4. 图像模糊(保存时选择高DPI,如300dpi)

Q2:如何批量生成不同内容的二维码?

A:将数据存储在列表或CSV文件中,用循环遍历生成。例如:

ini 复制代码
import csv

data_list = [
    {"id": 1, "url": "https://example.com/1"},
    {"id": 2, "url": "https://example.com/2"}
]

for item in data_list:
    qr = qrcode.QRCode()
    qr.add_data(item["url"])
    # ...其余生成代码...
    img.save(f"qr_{item['id']}.png")

Q3:条形码和二维码有什么区别?

A:

特性 二维码 条形码
数据容量 可存储数百字符 通常20-30字符
纠错能力 高(可恢复30%损坏) 低(部分损坏无法识别)
扫描方向 360度全向扫描 需固定方向扫描
应用场景 网址、联系信息、复杂数据 商品价格、库存管理

Q4:如何调整二维码的尺寸?

A:通过box_sizeversion参数控制:

  • box_size:每个"点"的像素数(如设为10,则10x10像素一个点)

  • version:二维码版本(1-40),版本越高尺寸越大,可存储更多数据

    例如生成大尺寸二维码:

    ini 复制代码
    qr = qrcode.QRCode(
        version=10,  # 较大版本
        box_size=15,  # 每个点15像素
        border=4
    )

Q5:生成的图像有锯齿怎么办?

A:在保存时指定抗锯齿参数(Pillow的resize方法):

ini 复制代码
img = img.resize((800, 800), Image.LANCZOS)  # 高质量缩放
img.save("smooth_qr.png", dpi=(300, 300))   # 高DPI保存

结语

从基础生成到高级定制,Python提供了完整的工具链让码生成变得简单而灵活。通过掌握颜色、形状、Logo嵌入等技巧,你可以创建出既实用又美观的码。记住:高纠错级别是Logo嵌入的安全保障,颜色对比度是扫描成功的关键,而批量处理能力则是大规模应用的基石。现在,用这些知识去设计你的专属码吧!

相关推荐
老白干19 小时前
jjwt 0.9.1 在 JDK 11+ 上的两个“坑”与完整解决方案
java·python·log4j
笨鸟先飞,勤能补拙1 天前
AI 赋能网络安全:技术全景、成熟度评估与实战案例
人工智能·python·安全·web安全·网络安全·sqlite·github
长和信泰光伏储能1 天前
京津冀光伏发电:绿色能源的未来之路
python·能源
浦信仿真大讲堂1 天前
从重复操作到自动化闭环:如何让 CST 与 Python 真正协同起来
python·自动化·cst·仿真软件·达索软件
Gu Gu Study1 天前
ScoutLoop开放域深度研究引擎(agent的初步设计想法)
人工智能·python
卷无止境1 天前
写代码这件事,到底该讲究点什么?
后端·python
卷无止境1 天前
循环复杂度到底在算什么,Python 代码怎么才能写得让人一看就懂
后端·python
lpfasd1231 天前
MediaCrawler 项目深度分析
chrome·python·chrome devtools
Dxy12393102161 天前
Python项目打包成EXE完整教程(PyInstaller实战避坑)
开发语言·python
bamb001 天前
一个项目带你入门AI应用开发01
python