二维码和条形码已成为现代信息传递的重要工具,从支付扫码到产品溯源,从活动签到到数据存储,这些黑白方块和线条背后藏着巨大的应用潜力。但默认生成的码往往千篇一律,如何让它们既实用又美观?本文将带你用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_color和back_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")
四、核心技能:在码中嵌入Logo
4.1 二维码嵌入Logo
关键步骤:
- 生成基础二维码
- 用Pillow打开二维码图像
- 打开Logo图像并调整大小
- 将Logo粘贴到二维码中心
- 保存最终图像
完整代码:
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嵌入更敏感,建议:
- 将Logo放在条形码上方/下方空白处
- 避免遮挡条形码本身
- 使用高对比度颜色
示例代码:
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:检查以下原因:
- 纠错级别设置过低(建议使用
ERROR_CORRECT_H) - Logo过大遮挡了关键定位图案(确保Logo不超过二维码面积的30%)
- 颜色对比度不足(黑白对比最可靠,彩色需确保明暗差异明显)
- 图像模糊(保存时选择高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_size和version参数控制:
-
box_size:每个"点"的像素数(如设为10,则10x10像素一个点) -
version:二维码版本(1-40),版本越高尺寸越大,可存储更多数据例如生成大尺寸二维码:
iniqr = 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嵌入的安全保障,颜色对比度是扫描成功的关键,而批量处理能力则是大规模应用的基石。现在,用这些知识去设计你的专属码吧!