117 lines
3.7 KiB
Python
117 lines
3.7 KiB
Python
|
import tkinter as tk
|
|||
|
from tkinter import filedialog, messagebox
|
|||
|
import qrcode
|
|||
|
from PIL import Image
|
|||
|
|
|||
|
|
|||
|
# 生成二维码的函数
|
|||
|
def generate_qr():
|
|||
|
text = text_input.get("1.0", tk.END).strip() # 获取用户输入的文字
|
|||
|
if not text:
|
|||
|
messagebox.showerror("错误", "请输入内容!")
|
|||
|
return
|
|||
|
|
|||
|
# 选择保存路径
|
|||
|
save_path = filedialog.asksaveasfilename(
|
|||
|
defaultextension=".png",
|
|||
|
filetypes=[("PNG 图片", "*.png"), ("所有文件", "*.*")]
|
|||
|
)
|
|||
|
if not save_path:
|
|||
|
return # 用户取消保存时退出
|
|||
|
|
|||
|
try:
|
|||
|
# 调用 qrcode 库生成二维码
|
|||
|
qr = qrcode.QRCode(
|
|||
|
version=1, # 控制二维码大小,1~40
|
|||
|
error_correction=qrcode.constants.ERROR_CORRECT_H, # 容错率,可选 L, M, Q, H
|
|||
|
box_size=10, # 每个模块的像素大小
|
|||
|
border=4, # 边框宽度(模块单位)
|
|||
|
)
|
|||
|
qr.add_data(text) # 添加内容
|
|||
|
qr.make(fit=True) # 适配大小
|
|||
|
|
|||
|
# 生成二维码图片
|
|||
|
qr_img = qr.make_image(fill_color="black", back_color="white").convert("RGBA")
|
|||
|
|
|||
|
# 将二维码中的白色背景透明化
|
|||
|
qr_img = make_background_transparent(qr_img)
|
|||
|
|
|||
|
# 如果选择了背景图片,将其融合到二维码中
|
|||
|
if bg_image_path.get():
|
|||
|
bg_img = Image.open(bg_image_path.get()).convert("RGBA")
|
|||
|
qr_img = blend_qr_with_bg(qr_img, bg_img)
|
|||
|
|
|||
|
qr_img.save(save_path) # 保存图片
|
|||
|
messagebox.showinfo("成功", f"二维码已生成并保存至:\n{save_path}")
|
|||
|
except Exception as e:
|
|||
|
messagebox.showerror("错误", f"生成二维码失败:\n{e}")
|
|||
|
|
|||
|
|
|||
|
# 选择背景图片的函数
|
|||
|
def select_bg_image():
|
|||
|
file_path = filedialog.askopenfilename(
|
|||
|
filetypes=[("图片文件", "*.png;*.jpg;*.jpeg"), ("所有文件", "*.*")]
|
|||
|
)
|
|||
|
if file_path:
|
|||
|
bg_image_path.set(file_path)
|
|||
|
bg_label.config(text=f"已选择背景图片:{file_path}")
|
|||
|
|
|||
|
|
|||
|
# 将二维码和背景图片融合的函数
|
|||
|
def blend_qr_with_bg(qr_img, bg_img):
|
|||
|
# 调整背景图片大小与二维码一致
|
|||
|
bg_img = bg_img.resize(qr_img.size, Image.Resampling.LANCZOS)
|
|||
|
|
|||
|
# 将二维码与背景图片融合
|
|||
|
# 将二维码图像直接粘贴到背景图上
|
|||
|
bg_img.paste(qr_img, (0, 0), qr_img)
|
|||
|
|
|||
|
return bg_img
|
|||
|
|
|||
|
|
|||
|
# 将二维码图像中的白色背景转为透明
|
|||
|
def make_background_transparent(img):
|
|||
|
# 获取图片的像素数据
|
|||
|
img_data = img.getdata()
|
|||
|
|
|||
|
# 创建新的像素列表,透明化白色背景
|
|||
|
new_data = []
|
|||
|
for item in img_data:
|
|||
|
# 如果是白色背景(RGB: 255, 255, 255),则设置透明度为 0
|
|||
|
if item[0] == 255 and item[1] == 255 and item[2] == 255:
|
|||
|
new_data.append((255, 255, 255, 0)) # 透明
|
|||
|
else:
|
|||
|
new_data.append(item) # 保留原始颜色
|
|||
|
|
|||
|
# 更新图像数据
|
|||
|
img.putdata(new_data)
|
|||
|
return img
|
|||
|
|
|||
|
|
|||
|
# 创建主窗口
|
|||
|
window = tk.Tk()
|
|||
|
window.title("二维码生成器")
|
|||
|
window.geometry("500x400")
|
|||
|
|
|||
|
# 创建输入框和标签
|
|||
|
label = tk.Label(window, text="请输入内容:", font=("Arial", 12))
|
|||
|
label.pack(pady=10)
|
|||
|
|
|||
|
text_input = tk.Text(window, height=6, width=50)
|
|||
|
text_input.pack(pady=10)
|
|||
|
|
|||
|
# 背景图片选择
|
|||
|
bg_image_path = tk.StringVar() # 用于存储背景图片路径
|
|||
|
bg_button = tk.Button(window, text="选择背景图片", font=("Arial", 12), command=select_bg_image)
|
|||
|
bg_button.pack(pady=5)
|
|||
|
|
|||
|
bg_label = tk.Label(window, text="未选择背景图片", font=("Arial", 10))
|
|||
|
bg_label.pack(pady=5)
|
|||
|
|
|||
|
# 创建生成按钮
|
|||
|
generate_button = tk.Button(window, text="生成二维码", font=("Arial", 12), command=generate_qr)
|
|||
|
generate_button.pack(pady=10)
|
|||
|
|
|||
|
# 启动主循环
|
|||
|
window.mainloop()
|