[Python] 纯文本查看 复制代码
import os
import cv2
import mysql.connector
import numpy as np
from tkinter import filedialog
from tkinter import *
from datetime import datetime, timedelta
import json
from tkinter import messagebox, Toplevel
from concurrent.futures import ThreadPoolExecutor
import requests
from threading import Thread
import random
# 建立连接
mydb = mysql.connector.connect(
host="你的服务器IP",
user="数据库账号",
password="数据库密码",
database="数据库名"
)
# 创建游标
mycursor = mydb.cursor()
# 从视频中提取图片
# 修改 extract_images_from_video 函数以添加弹窗提示
def extract_images_from_video(video_path, output_dir, n_images):
if n_images > 1:
messagebox.showwarning("提示", "如果分割多张图片,有时候只能扣一张,国外接口有并发限制,同一个视频尽量就分割一张,不然浪费次数!")
vidcap = cv2.VideoCapture(video_path)
total_frames = int(vidcap.get(cv2.CAP_PROP_FRAME_COUNT))
frames_step = total_frames // n_images
success, image = vidcap.read()
count = 0
while success:
if count % frames_step == 0:
cv2.imwrite(os.path.join(output_dir, "frame%d.jpg" % count), image)
remove_background(os.path.join(output_dir, "frame%d.jpg" % count))
success, image = vidcap.read()
count += 1
# 修改 remove_background 函数,使其支持异步执行
with open('api.json') as f:
config = json.load(f)
removebg_api_key = config['removebg_api_key']
def remove_background(image_path):
def update_warning_label():
warning_text.set("正在抠图中,请稍后!") # 更新提示内容
root.after(0, update_warning_label) # 在主线程中更新 GUI
response = requests.post(
'https://api.remove.bg/v1.0/removebg',
files={'image_file': open(image_path, 'rb')},
data={'size': 'auto'},
headers={'X-Api-Key': removebg_api_key},
)
if response.status_code == requests.codes.ok:
with open(image_path.replace(".jpg", ".png"), 'wb') as out:
out.write(response.content)
thread = Thread(target=add_gradient_background, args=(image_path.replace(".jpg", ".png"),))
thread.start()
else:
print("错误:", response.status_code, response.text)
# 读取颜色列表
with open('colors.json') as f:
color_list = json.load(f)['colors']
# 随机选择一组颜色
color1, color2 = random.choice(color_list)
# 现在color1和color2就是一组随机选择的颜色
def add_gradient_background(image_path):
def update_warning_label():
warning_text.set("正在换背景中,请稍后!") # 更新提示内容
def reset_warning_label():
warning_text.set("已处理完毕,请查看输出文件夹!") # 恢复默认提示
root.after(0, update_warning_label) # 在主线程中更新 GUI
image = cv2.imread(image_path, cv2.IMREAD_UNCHANGED)
h, w = image.shape[:2]
gradient = np.zeros((h, w, 3), dtype=np.uint8)
# 创建渐变背景
for i in range(w):
if i < w / 2:
gradient[:, i, :] = [(color2[j] - color1[j]) * (i / w * 2) + color1[j] for j in range(3)]
else:
gradient[:, i, :] = [(color1[j] - color2[j]) * ((i - w / 2) / w * 2) + color2[j] for j in range(3)]
alpha_channel = image[:, :, 3] / 255.
result = (image[:, :, :3] * alpha_channel[..., None] + gradient * (1 - alpha_channel[..., None])).astype(np.uint8)
cv2.imwrite(image_path.replace(".png", "_with_gradient.png"), result)
root.after(0, reset_warning_label) # 在函数末尾恢复默认提示
def validate_input(user_id, code):
# SQL 查询语句
query = "SELECT * FROM iscode WHERE code = %s"
value = (code,)
# 执行 SQL 查询
mycursor.execute(query, value)
# 获取所有记录
records = mycursor.fetchall()
# 如果找到记录
if records:
for row in records:
db_user_id = row[2]
db_creation_date = row[3]
db_days = row[4]
# 检查激活码是否已过期
if datetime.now() > db_creation_date + timedelta(days=db_days):
print("您的激活码已过期。")
return False
# 检查激活码是否属于当前用户
if user_id != db_user_id:
print("您的用户ID与激活码不匹配。")
return False
print("激活码有效并已激活。")
return True
else:
print("无效的激活码。")
return False
def activate(user_id):
code = entry2.get()
if validate_input(user_id, code):
# 用户激活成功,将用户ID和激活码写入配置文件
with open('user_config.json', 'w') as f:
json.dump({'user_id': user_id, 'code': code}, f)
messagebox.showinfo('成功', '激活成功')
root.withdraw() # 隐藏激活窗口
openfile()
else:
messagebox.showwarning('错误', '无效的, 已使用的或过期的激活码')
def openfile_videos(entry):
update_warning_label() # 在开始执行 extract_images_from_video 之前更新提示标签
video_path = filedialog.askopenfilename(filetypes=(("MP4 files", "*.mp4"), ("all files", "*.*")))
n_images = int(entry.get())
messagebox.showinfo("下一步", "请选择输出目录")
output_dir = filedialog.askdirectory()
thread = Thread(target=extract_images_from_video, args=(video_path, output_dir, n_images))
thread.start()
def openfile():
# 创建新的tkinter窗口
root2 = Toplevel(root)
root2.title("从视频提取图片")
# 创建标签和输入框
label1 = Label(root2, text="图片数量:")
label1.grid(row=0, column=0, padx=20, pady=20, sticky=W)
entry = Entry(root2)
entry.insert(0, "1") # 插入默认数据
entry.grid(row=0, column=1, padx=20, pady=20, sticky=E)
# 创建红色提示标签
global warning_text # 将 warning_text 声明为全局变量
warning_text = StringVar() # 创建一个 StringVar 变量
warning_text.set("你的软件还未启动,请先输入需要分割的数量!") # 默认提示
warning_label = Label(root2, textvariable=warning_text, fg="red")
warning_label.grid(row=1, column=0, columnspan=2)
# 创建按钮
button = Button(root2, text="打开视频文件", command=lambda: openfile_videos(entry))
button.grid(row=2, column=0, columnspan=2, padx=20, pady=20)
# 在Tkinter窗口中添加Label
status_var = StringVar()
status_label = Label(root, textvariable=status_var)
status_label.grid(row=3, column=0, columnspan=2, padx=20, pady=20)
# 设置窗口尺寸并使其不可更改
root2.geometry("280x150")
root2.resizable(False, False)
def update_warning_label():
warning_text.set("正在分割图片,请稍后!") # 更新提示内容
# 创建tkinter窗口
root = Tk()
root.title("激活")
# 创建标签和输入框
label1 = Label(root, text="用户ID:")
label1.grid(row=0, column=0, padx=20, pady=20, sticky=W)
entry1 = Entry(root)
entry1.grid(row=0, column=1, padx=20, pady=20, sticky=E)
label2 = Label(root, text="激活码:")
label2.grid(row=1, column=0, padx=20, pady=20, sticky=W)
entry2 = Entry(root)
entry2.grid(row=1, column=1, padx=20, pady=20, sticky=E)
# 检查配置文件是否存在,如果存在就读取用户ID和激活码
if os.path.exists('user_config.json'):
with open('user_config.json', 'r') as f:
config = json.load(f)
entry1.insert(0, config['user_id'])
entry2.insert(0, config['code'])
# 创建按钮
button = Button(root, text="点击激活", command=lambda: activate(entry1.get()))
button.grid(row=2, column=0, columnspan=2, padx=20, pady=20)
# 设置窗口尺寸并使其不可更改
root.geometry("300x200")
root.resizable(False, False)
try:
root.mainloop()
except KeyboardInterrupt:
print("程序已被用户手动关闭")
# 这里可以进行一些清理工作,例如关闭数据库连接
mydb.close()