1 Star 0 Fork 105

mynameisi/batch_processing_image_question

加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
batch_transform_app.py 9.81 KB
一键复制 编辑 原始数据 按行查看 历史
mynameisi 提交于 2024-05-24 16:39 . init
import os # 导入os模块,用于处理文件和目录
import cv2 as cv # 导入cv2模块,用于图像处理
import numpy as np # 导入numpy模块,用于处理大型多维数组和矩阵
from zipfile import ZipFile # 从zipfile模块导入ZipFile,用于处理ZIP文件
from tkinter import Tk, Button, filedialog, Scale, Label, OptionMenu, StringVar, Toplevel, ttk, messagebox # 导入tkinter模块,用于创建图形用户界面
from threading import Thread, Event # 从threading模块导入Thread和Event,用于创建和管理线程
from util import process_images_from_zip # 从util模块导入process_images_from_zip函数,用于处理ZIP文件中的图像
from util import load_config # 从util模块导入load_config函数,用于加载配置文件
import logging # 导入logging模块,用于记录日志
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(thread)d - %(message)s') # 配置日志记录器,设置日志级别、日志格式和日志输出位置
# %(thread)d 是需要打印的线程ID,这样可以区分不同的线程
class ImageProcessingApp: # 定义一个名为ImageProcessingApp的类,用于创建图像处理应用
# 首先定义一个初始化函数,用于初始化应用
# 在这个函数中,我们将创建应用的根窗口,并设置应用的标题和默认窗口大小
# 然后,我们将创建应用的图形用户界面组件,并将它们添加到应用窗口
# 最后,我们将初始化应用的一些属性,如线程事件、进度值和ZIP文件路径
def __init__(self, root):
config = load_config() # 从配置文件中加载配置
logging.info('开始函数: __init__ 开始搭建APP的图形用户界面') # 记录日志,表示开始初始化应用
self.root = root # 设置应用的根窗口
self.root.title('Image Processing App') # 设置应用的标题
self.root.geometry('500x400') # 设置应用的默认窗口大小
# 创建一个按钮,用于选择ZIP文件
self.zip_btn = Button(root, text="Select ZIP", command=self.select_zip)
self.zip_btn.pack() # 将按钮添加到应用窗口
# 创建一个标签,用于显示选择的文件
self.selected_file_label = Label(root, text="Selected File: None")
self.selected_file_label.pack() # 将标签添加到应用窗口
# 创建一个标签,用于显示缩放范围
self.scale_label = Label(root, text="Scale Range")
self.scale_label.pack() # 将标签添加到应用窗口
self.scale_min = Scale(root, from_=config['scale_min'], to=config['scale_middle'], resolution=0.1, orient="horizontal", label="Min") # 创建一个滑块,用于设置最小缩放值
self.scale_min.set(config['scale_min_default']) # 设置滑块的默认值
self.scale_min.pack() # 将滑块添加到应用窗口
self.scale_max = Scale(root, from_=config['scale_middle'], to=config['scale_max'], resolution=0.1, orient="horizontal", label="Max") # 创建一个滑块,用于设置最大缩放值
self.scale_max.set(config['scale_max_default']) # 设置滑块的默认值
self.scale_max.pack() # 将滑块添加到应用窗口
# 创建一个滑块,用于设置处理的图像数量
self.num_images_scale = Scale(root, from_=config['num_images_min'], to=config['num_images_max'], orient="horizontal", label="Number of Images")
self.num_images_scale.set(config['num_images_default']) # 设置滑块的默认值
self.num_images_scale.pack() # 将滑块添加到应用窗口
# 创建一个选项菜单,用于选择输出的图像通道数,可以是RGB、Grayscale或Binary
self.output_type = StringVar(root) # 创建一个字符串变量,用于存储输出类型
self.output_type.set(config['output_type_default']) # 设置字符串变量的默认值
self.option_menu = OptionMenu(root, self.output_type, *config['output_type_options']) # 创建一个选项菜单,用于选择输出类型
self.option_menu.pack() # 将选项菜单添加到应用窗口
# 创建一个按钮,用于开始处理图像
self.process_btn = Button(root, text="Process", command=self.start_processing, state="disabled")
self.process_btn.pack() # 将按钮添加到应用窗口
# 创建一个按钮,用于取消处理图像
self.cancel_btn = Button(root, text="Cancel", command=self.cancel_processing, state="disabled")
self.cancel_btn.pack() # 将按钮添加到应用窗口
# 添加用于显示进度的Label和StringVar
self.progress_var = StringVar(root) # 创建一个字符串变量,用于存储进度信息
self.progress_label = Label(root, textvariable=self.progress_var) # 创建一个标签,用于显示进度信息
self.progress_label.pack() # 将标签添加到应用窗口
# 添加用于显示进度的进度条
self.progress_bar = ttk.Progressbar(root, orient='horizontal', mode='determinate') # 创建一个进度条,用于显示处理进度
self.progress_bar.pack(fill='x') # 将进度条添加到应用窗口
# 初始化应用的一些属性
self.thread_event = Event() # 创建一个线程事件,用于处理线程
self.progress_value = 0 # 初始化进度值
self.zip_path = None # 初始化ZIP文件路径
def select_zip(self): # 定义一个函数,用于选择ZIP文件
self.zip_path = filedialog.askopenfilename(filetypes=[("ZIP files", "*.zip")]) # 打开文件对话框,让用户选择ZIP文件
if self.zip_path: # 如果用户选择了文件
logging.info(f'选择的zip文件: {self.zip_path}') # 记录日志
self.selected_file_label['text'] = "Selected File: " + os.path.basename(self.zip_path) # 更新标签的文本,显示选择的文件
self.process_btn.config(state="normal") # 如果用户选择了文件,使处理按钮可用
def threaded_image_processing(self): # 定义一个函数,用于在新线程中处理图像
# log the start of function
logging.info('开始函数: threaded_image_processing') # 记录日志,表示开始在新线程中处理图像
if not self.zip_path: # 如果没有选择ZIP文件
return # 结束函数
# 提示用户正在进行处理
self.progress_var.set("Processing images...") # 更新进度信息
self.cancel_btn.config(state="normal") # 使取消按钮可用
self.process_btn.config(state="disabled") # 禁用处理按钮以避免重复点击
# 更新图像处理参数,这些将是您从GUI控件获取的值
scale_min = self.scale_min.get() # 获取最小缩放值
scale_max = self.scale_max.get() # 获取最大缩放值
num_images = self.num_images_scale.get() # 获取处理的图像数量
#log all the parameters
logging.info(f'图像处理参数: scale_min={scale_min}, scale_max={scale_max}, num_images={num_images}') # 记录日志,显示图像处理参数
try:
self.progress_value = 0 # 初始化进度值
self.progress_bar['value'] = self.progress_value # 更新进度条的值
process_images_from_zip(self.zip_path,
scale_min=scale_min,
scale_max=scale_max,
num_images=num_images,
progress_callback=self.update_progress,
thread_event=self.thread_event,
output_type=self.output_type.get()) # 调用util.py中的函数处理图像
except Exception as e:
self.progress_var.set(f"Error: {e}") # 如果出现异常,更新进度信息,显示错误信息
return # 结束函数
# 结束处理后的操作
self.progress_var.set("Processing completed!") # 更新进度信息,表示处理完成
logging.info('图像处理完成') # 记录日志,表示图像处理完成
self.process_btn.config(state="normal") # 重新启用处理按钮
self.cancel_btn.config(state="disabled") # 禁用取消按钮
def start_processing(self): # 定义一个函数,用于开始处理图像
logging.info('开始图像处理') # 记录日志,表示开始处理图像
self.thread_event.clear() # 清除线程事件
thread = Thread(target=self.threaded_image_processing) # 创建一个线程,用于处理图像
thread.daemon = True # 设置线程为守护线程
# 这种守护线程将在主线程结束时自动结束
# 这样,当用户关闭应用时,守护线程也会结束
# 比较适合这种需要在后台运行的操作,保持前台用户界面的响应性的操作
thread.start() # 启动线程
def update_progress(self, progress): # 定义一个函数,用于更新进度条的进度
logging.info(f'更新进度: {progress}') # 记录日志,显示更新的进度
self.progress_value = progress # 更新进度值
self.progress_bar['value'] = self.progress_value # 更新进度条的值
self.root.update_idletasks() # 强制更新应用的图形用户界面,以显示进度条的更新
def cancel_processing(self): # 定义一个函数,用于取消处理图像
logging.info('用户取消了图像处理') # 记录日志,表示用户取消了图像处理
self.thread_event.set() # 设置线程事件
root = Tk() # 创建一个Tk对象,作为应用的根窗口
app = ImageProcessingApp(root) # 创建一个ImageProcessingApp对象,作为应用
root.mainloop() # 启动应用的主循环
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/mynameisi/batch_processing_image_question.git
git@gitee.com:mynameisi/batch_processing_image_question.git
mynameisi
batch_processing_image_question
batch_processing_image_question
main

搜索帮助