python 对图片增加边框,logo贴图,获取图片exif参数,填写图片文本内容-CSDN博客
- import tkinter as tk
- from tkinter import ttk
- import os
- import glob
- import json
- import tkinter.messagebox as messagebox # 弹出提示框
- from PIL import Image, ImageDraw, ImageFont
- import exifread
-
- def photo_exif(image_path):
-
- f = open(image_path, 'rb')
-
- tags = exifread.process_file(f)
-
- # 打印所有照片信息,会以键值对的方法保存
- # for tag in tags.keys():
- # print("Key: {0}, value {1}".format(tag, tags[tag]))
- # print(str(tags['EXIF FocalLength']) + 'mm', tags['EXIF ExposureTime'], 'ISO' + str(tags['EXIF ISOSpeedRatings']))
- return tags
-
-
-
- def add_logo_with_text(image_path, logo_path, logo_size, text1, text2, text3, font_path, font_size, font_color, border_size,
- border_color, output_path):
- # 打开原始图片
- image = Image.open(image_path).convert("RGB")
- width, height = image.size
-
- # 计算边框区域大小和位置
- font = ImageFont.truetype(font_path, font_size)
- text1_width, text1_height = font.getsize(text1)
- text2_width, text2_height = font.getsize(text2)
- text3_width, text3_height = font.getsize(text3)
- text_width = max(text1_width, text2_width, text3_width)
- text_height = text1_height + text2_height + text3_height
- border_width = logo_size[0] + text_width + border_size * 3
- border_height = max(logo_size[1], text_height) + border_size * 2
- border_position = ((width - border_width) // 2, height)
-
- # 打开logo图片并调整大小
- logo = Image.open(logo_path).resize(logo_size, Image.ANTIALIAS)
-
- # 创建新的图片
- new_width = width
- new_height = height + border_height
- new_image = Image.new("RGB", (new_width, new_height), "white")
-
- # 将原始图片复制到新图片的顶部
- new_image.paste(image, (0, 0, width, height))
-
- # 在新图片上绘制边框
- draw = ImageDraw.Draw(new_image)
- border_rect = (border_position[0], height, border_position[0] + border_width, height + border_height)
- draw.rectangle(border_rect, fill=None, outline=border_color, width=border_size)
-
- # 在边框区域内绘制logo图片
- logo_position = (border_position[0] + border_size, height + (border_height - logo_size[1]) // 2)
- new_image.paste(logo, logo_position)
-
- # 在边框区域内绘制文本
- text1_position = (border_position[0] + border_size * 2 + logo_size[0], height + (border_height - text_height) // 2)
- text2_position = (border_position[0] + border_size * 2 + logo_size[0], text1_position[1] + text1_height)
- text3_position = (border_position[0] + border_size * 2 + logo_size[0], text2_position[1] + text2_height)
- draw.text(text1_position, text1, font=font, fill=font_color)
- draw.text(text2_position, text2, font=font, fill=font_color)
- draw.text(text3_position, text3, font=font, fill=font_color)
-
- # 保存合成后的图片
- new_image.save(output_path)
-
- def generate_callback():
- # 获取下拉列表的选中值
- param1 = combo1.get()
- param2 = combo2.get()
- param3 = combo3.get()
- param4 = combo4.get()
- param5 = combo5.get()
- param6 = combo6.get()
- param66 = combo66.get()
- param7 = combo7.get()
-
- # 判断输入是否为空,弹出提示框
- if not param1:
- messagebox.showerror("Error", "图片路径不能为空!")
- return
- if not param2:
- messagebox.showerror("Error", "Logo路径不能为空!")
- return
- if not param3:
- messagebox.showerror("Error", "参数1不能为空!")
- return
- if not param4:
- messagebox.showerror("Error", "参数2不能为空!")
- return
- if not param5:
- messagebox.showerror("Error", "参数3不能为空!")
- return
- if not param6:
- messagebox.showerror("Error", "字体路径不能为空!")
- return
- if not param66:
- messagebox.showerror("Error", "字体大小不能为空!")
- return
- if not param7:
- messagebox.showerror("Error", "输出路径不能为空!")
- return
-
- # 调用后端处理函数,并传递参数
- # print(param1, param2, param22, param3, param4, param5, param6, param66, param7)
-
- # 示例用法
- # 照片路径
- image_path = param1
- # logo图片路径
- logo_path = param2
- # logo图片大小
- logo_size = (255, 255)
- # 图片信息
- tags = photo_exif(image_path)
- text1 = param3
- text2 = param4
- text3 = param5
- # 字体路径
- font_path = param6
- font_size = 55
- font_color = (0, 0, 0) # 黑色
- border_size = 55
- border_color = (255, 255, 255) # 白色
- # 输出照片 .后缀为png为无损图片 ,jpg为压缩后的图片
- output_path = str(image_path)+str(param7)
-
- add_logo_with_text(image_path, logo_path, logo_size, text1, text2, text3, font_path, font_size, font_color, border_size,
- border_color, output_path)
- print("图片已保存至:", output_path)
- messagebox.showinfo("提示", "图片已保存至:\n" + output_path)
-
-
- def on_file_list_double_click(event):
- selected_index = event.widget.curselection()
- if selected_index:
- selected_file = event.widget.get(selected_index)
- combo1.set(selected_file)
-
- def on_logo_list_double_click(event):
- selected_index = event.widget.curselection()
- if selected_index:
- selected_file = event.widget.get(selected_index)
- combo2.set(selected_file)
-
- def on_font_list_double_click(event):
- selected_index = event.widget.curselection()
- if selected_index:
- selected_file = event.widget.get(selected_index)
- combo6.set(selected_file)
-
- # 创建主窗口
- root = tk.Tk()
-
-
- # 读取json文件参数
- f = open('config.json', 'r', encoding='utf-8')
- content = f.read()
- a = json.loads(content)
-
- # 创建参数名称和下拉列表的组件
- label1 = tk.Label(root, text="图片路径:")
- combo1 = ttk.Combobox(root, state="normal", values=a["param1"])
- label2 = tk.Label(root, text="logo路径:")
- combo2 = ttk.Combobox(root, state="normal", values=a["param2"])
- label3 = tk.Label(root, text="参数1:")
- combo3 = ttk.Combobox(root, state="normal", values=a["param3"])
- label4 = tk.Label(root, text="参数2:")
- combo4 = ttk.Combobox(root, state="normal", values=a["param4"])
- label5 = tk.Label(root, text="参数3:")
- combo5 = ttk.Combobox(root, state="normal", values=a["param5"])
- label6 = tk.Label(root, text="字体路径:")
- combo6 = ttk.Combobox(root, state="normal", values=a["param6"])
- label66 = tk.Label(root, text="字体大小:")
- combo66 = ttk.Combobox(root, state="normal", values=a["param66"])
- label7 = tk.Label(root, text="输出路径:")
- combo7 = ttk.Combobox(root, state="normal", values=a["param7"])
-
- # label7 = tk.Label(root, text="输出路径:")
- # combo7 = ttk.Combobox(root, state="normal", values=["选项1", "选项2", "选项3"])
-
- # 设置下拉框的高度和宽度
- combo1.configure(width=68)
- combo2.configure(width=68)
- combo3.configure(width=68)
- combo4.configure(width=68)
- combo5.configure(width=68)
- combo6.configure(width=68)
- combo66.configure(width=68)
- combo7.configure(width=68)
-
-
-
- # 创建生成按钮并绑定回调函数
- generate_btn = tk.Button(text="生成", command=generate_callback ,width=79 ,height=2)
-
- # 使用grid布局来放置各个组件
- label1.grid(row=0, column=0)
- combo1.grid(row=0, column=1)
- label2.grid(row=1, column=0)
- combo2.grid(row=1, column=1)
- label3.grid(row=2, column=0)
- combo3.grid(row=2, column=1)
- label4.grid(row=3, column=0)
- combo4.grid(row=3, column=1)
- label5.grid(row=4, column=0)
- combo5.grid(row=4, column=1)
- label6.grid(row=5, column=0)
- combo6.grid(row=5, column=1)
- label66.grid(row=6, column=0)
- combo66.grid(row=6, column=1)
- label7.grid(row=7, column=0)
- combo7.grid(row=7, column=1)
- generate_btn.grid(row=8, columnspan=2) # 使用columnspan设置按钮横跨两列
-
- # 设置默认选中值
- combo1.current(0)
- combo2.current(0)
- combo3.current(0)
- combo4.current(0)
- combo5.current(0)
- combo6.current(0)
- combo66.current(0)
- combo7.current(0)
-
- # 添加标题
- title_label = tk.Label(root, text="文件路径:")
- title_label.grid(row=0, column=2, sticky="w")
-
- # 添加标题
- logo_title_label = tk.Label(root, text="Logo路径:")
- logo_title_label.grid(row=0, column=4, sticky="w")
-
- font_title_label = tk.Label(root, text="字体路径:")
- font_title_label.grid(row=0, column=6, sticky="w")
-
- # 获取当前py文件目录下的所有文件路径
- file_paths = glob.glob('*')
-
- # 创建文件路径列表框组件
- file_listbox_var = tk.StringVar(value=file_paths)
- file_listbox = tk.Listbox(root, listvariable=file_listbox_var)
- file_listbox.grid(row=1, column=2, rowspan=7, padx=10, pady=10, sticky="nsew")
-
- # 绑定双击事件处理函数
- file_listbox.bind('
' , on_file_list_double_click) -
- # 设置列表框自动填充满父容器
- root.grid_rowconfigure(1, weight=1)
- root.grid_columnconfigure(2, weight=1)
-
- # 创建滚动条
- file_scrollbar = tk.Scrollbar(root, orient="vertical", command=file_listbox.yview)
- file_scrollbar.grid(row=1, column=3, rowspan=7, sticky="ns")
-
- # 将滚动条与文件路径列表框关联
- file_listbox.configure(yscrollcommand=file_scrollbar.set)
-
- # 创建logo路径列表框组件
- logo_listbox_var = tk.StringVar(value=file_paths)
- logo_listbox = tk.Listbox(root, listvariable=logo_listbox_var)
- logo_listbox.grid(row=1, column=4, rowspan=7, padx=10, pady=10, sticky="nsew")
-
- # 绑定双击事件处理函数
- logo_listbox.bind('
' , on_logo_list_double_click) -
- # 创建滚动条
- logo_scrollbar = tk.Scrollbar(root, orient="vertical", command=logo_listbox.yview)
- logo_scrollbar.grid(row=1, column=5, rowspan=7, sticky="ns")
-
- # 将滚动条与logo路径列表框关联
- logo_listbox.configure(yscrollcommand=logo_scrollbar.set)
-
- # 创建字体路径列表框组件
- font_listbox_var = tk.StringVar(value=file_paths)
- font_listbox = tk.Listbox(root, listvariable=font_listbox_var)
- font_listbox.grid(row=1, column=6, rowspan=7, padx=10, pady=10, sticky="nsew")
-
- # 绑定双击事件处理函数
- font_listbox.bind('
' , on_font_list_double_click) -
- # 创建滚动条
- font_scrollbar = tk.Scrollbar(root, orient="vertical", command=font_listbox.yview)
- font_scrollbar.grid(row=1, column=7, rowspan=7, sticky="ns")
-
- # 将滚动条与字体路径列表框关联
- font_listbox.configure(yscrollcommand=font_scrollbar.set)
-
- #
- # root.geometry("900x400") # 设置窗口的宽度为600个像素,高度为400个像素
-
- # 运行主循环
- root.mainloop()

