python 图片下面加边框TK界面

python 对图片增加边框,logo贴图,获取图片exif参数,填写图片文本内容-CSDN博客

python 复制代码
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('<Double-Button-1>', 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('<Double-Button-1>', 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('<Double-Button-1>', 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()
相关推荐
hummhumm4 分钟前
第 12 章 - Go语言 方法
java·开发语言·javascript·后端·python·sql·golang
hummhumm4 分钟前
第 8 章 - Go语言 数组与切片
java·开发语言·javascript·python·sql·golang·database
互联网杂货铺26 分钟前
基于Selenium+Python的web自动化测试框架(附框架源码+项目实战)
自动化测试·软件测试·python·selenium·测试工具·单元测试·测试用例
myheartgo-on1 小时前
PySpark——Python与大数据
大数据·python·信息可视化
weixin_478689761 小时前
【回溯法】——组合总数
数据结构·python·算法
天天要nx1 小时前
D68【python 接口自动化学习】- python基础之数据库
数据库·python
山山而川 潺潺如镜1 小时前
杰控通过 OPCproxy 获取数据发送到服务器
python
V搜xhliang02462 小时前
基于深度学习的地物类型的提取
开发语言·人工智能·python·深度学习·神经网络·学习·conda
API快乐传递者2 小时前
除了网页标题,还能用爬虫抓取哪些信息?
开发语言·爬虫·python
豌豆花下猫2 小时前
REST API 已经 25 岁了:它是如何形成的,将来可能会怎样?
后端·python·ai