二、软件功能:
无人职守就可以完成提取图片信息的任务,但是就得消耗豆包API的额度,不过貌似价格不是很高。在编程前,可以去申请一个豆包api,申请地址是:www.volcengine.com
一款图片信息提取工具,实现包括图片的导入、预览、信息提取、复制等功能,基本的样式如下:

微信图片_20250808172657.png (193.38 KB, 下载次数: 0)
下载附件
2025-8-8 17:27 上传
三、代码展示:
[Python] 纯文本查看 复制代码import os
import json
from tkinter import Tk, Label, Entry, filedialog, messagebox, StringVar, END, Button, LEFT,LabelFrame,Frame, Toplevel
from tkinter.scrolledtext import ScrolledText
from tkinter import PhotoImage, font
import threading
import base64
import pyperclip
from pathlib import Path
from openai import OpenAI
from PIL import Image, ImageTk
class ImageEssayEvaluator:
def __init__(self, root):
self.root = root
self.root.title("图片信息提取工具 | By Gordon")
self.setup_ui()
self.api = None
self.output_dir = os.path.join(os.getcwd(), "识别结果")
os.makedirs(self.output_dir, exist_ok=True)
self.current_scale = 1.0 # Track current zoom scale
self.image_files = [] # List to store multiple image paths
self.current_image_index = 0 # Track current image index
json_filename = "config.json"
if not os.path.exists(json_filename):
with open(json_filename, "w") as json_file:
json.dump({"api_key": self.api}, json_file)
print("JSON 文件已创建。")
else:
with open(json_filename, "r") as json_file:
data = json.load(json_file)
self.api = data.get("api")
if self.api is None:
self.show_settings()
self.update_api_button_text()
def update_api_button_text(self):
"""根据API状态更新按钮文本"""
if self.api:
self.api_button.config(text="已加载API")
else:
self.api_button.config(text="设置API")
def setup_ui(self):
self.info_var = StringVar()
self.info_var.set("Tip: 请导入图片,识别结果将显示在下方文本框")
Label(self.root, textvariable=self.info_var, font=("微软雅黑", 12)).pack(pady=5)
frame = Frame(self.root)
frame.pack(padx=6)
Label(frame, text="图片路径:", font=("微软雅黑", 12)).pack(side='left')
self.image_path_entry = Entry(frame, width=60, font=("微软雅黑", 12))
self.image_path_entry.pack(side=LEFT, padx=5, pady=5)
self.api_button = Button(frame, text="设置API", font=("微软雅黑", 12), command=self.show_settings)
self.api_button.pack()
# Create a frame for the image and text display
main_frame = Frame(self.root)
main_frame.pack(padx=5, pady=5)
# Left Frame for Image Preview (no fixed height)
#self.preview_frame = Frame(main_frame, width=500)
self.preview_frame = LabelFrame(main_frame, text=" 预览图片文件",font=("微软雅黑", 12), width=400, height=460, padx=1, pady=1)
self.preview_frame.grid(row=0, column=0, padx=10, pady=10)
self.preview_frame.pack_propagate(False)
# Image preview label
self.image_label = Label(self.preview_frame)
self.image_label.pack(padx=10, pady=10)
# Frame for zoom and navigation buttons
button_frame = Frame(self.preview_frame)
button_frame.pack(side='bottom',pady=5)
# Zoom buttons (Up and Down) and Navigation buttons (Previous and Next)
self.zoom_in_button = Button(button_frame, text="放大", font=("微软雅黑", 12), command=self.zoom_in)
self.zoom_in_button.pack(side=LEFT, padx=5)
self.zoom_out_button = Button(button_frame, text="缩小", font=("微软雅黑", 12), command=self.zoom_out)
self.zoom_out_button.pack(side=LEFT, padx=5)
self.prev_button = Button(button_frame, text="上一张", font=("微软雅黑", 12), command=self.previous_image)
self.prev_button.pack(side=LEFT, padx=5)
self.next_button = Button(button_frame, text="下一张", font=("微软雅黑", 12), command=self.next_image)
self.next_button.pack(side=LEFT, padx=5)
# Right Frame for Text Display
#self.text_frame = Frame(main_frame, width=400, height=300)
self.text_frame = LabelFrame(main_frame, text=" 提取信息显示 ", font=("微软雅黑", 12), width=400, height=300, padx=1, pady=1)
self.text_frame.grid(row=0, column=1, padx=10, pady=10)
# Text display area
self.text_display = ScrolledText(self.text_frame, width=50, height=20, font=("微软雅黑", 12))
self.text_display.pack(padx=5, pady=5)
button_frame = Frame(self.root)
button_frame.pack(expand=True)
# Other buttons
Button(button_frame, text="导入图片", font=("微软雅黑", 12), command=self.load_image).pack(side="left", padx=90, pady=10)
Button(button_frame, text="提取信息", font=("微软雅黑", 12), command=self.start_evaluation).pack(side="left", padx=60, pady=10)
Button(button_frame, text="打开目录", font=("微软雅黑", 12), command=self.open_output_dir).pack(side="left", padx=60, pady=10)
Button(button_frame, text="复制信息", font=("微软雅黑", 12), command=self.copy_info).pack(side="left", padx=60, pady=10)
def show_settings(self):
self.settings_window = Toplevel(self.root)
self.settings_window.attributes('-topmost', True)
self.settings_window.title("豆包 API设置")
Label(self.settings_window, text="请把kimi的API放在这里,使用ctrl+V:").pack(pady=5)
self.api_var = StringVar()
self.entry = Entry(self.settings_window, textvariable=self.api_var, width=30, font=("微软雅黑", 12))
self.entry.pack()
confirm_button = Button(self.settings_window, text="确认", command=lambda: self.apply_settings())
confirm_button.pack(pady=10)
screen_width = self.settings_window.winfo_screenwidth()
screen_height = self.settings_window.winfo_screenheight()
self.settings_window.update_idletasks()
window_width = self.settings_window.winfo_width()
window_height = self.settings_window.winfo_height()
x_position = (screen_width - window_width) // 2
y_position = (screen_height - window_height) // 2
self.settings_window.geometry(f"{window_width}x{window_height}+{x_position}+{y_position}")
def apply_settings(self):
new_time = self.api_var.get()
self.api = new_time.strip()
data = {'api': self.api}
with open('config.json', 'w+') as f:
json.dump(data, f, indent=4)
self.settings_window.destroy()
def copy_info(self):
pyperclip.copy(self.text_display.get(1.0, END))
def load_image(self):
if len(str(self.api)) 1:
self.prev_button.config(state="normal" if self.current_image_index > 0 else "disabled")
self.next_button.config(state="normal" if self.current_image_index 0:
self.current_image_index -= 1
self.image_path_entry.delete(0, END)
self.image_path_entry.insert(0, self.image_files[self.current_image_index])
self.info_var.set(f"已加载图片: {os.path.basename(self.image_files[self.current_image_index])} ({self.current_image_index + 1}/{len(self.image_files)})")
self.current_scale = 1.0 # Reset zoom scale
self.display_image(self.image_files[self.current_image_index])
self.update_navigation_buttons()
def next_image(self):
if self.current_image_index = len(self.image_files):
messagebox.showwarning("警告", "请先加载图片")
return
image_path = self.image_files[self.current_image_index]
try:
img = Image.open(image_path)
# Estimate text area height (15 lines of font "微软雅黑" size 12)
text_font = font.Font(family="微软雅黑", size=12)
line_height = text_font.metrics("linespace")
target_height = int(line_height * 15 * self.current_scale)
# Calculate width based on aspect ratio
original_width, original_height = img.size
target_width = int(target_height * original_width / original_height)
img = img.resize((target_width, target_height), Image.Resampling.LANCZOS)
self.image_preview = ImageTk.PhotoImage(img)
self.image_label.config(image=self.image_preview)
# 更新路径栏显示当前图片(可选)
self.image_path_entry.delete(0, END)
self.image_path_entry.insert(0, image_path)
except Exception as e:
messagebox.showerror("错误", f"无法加载图片:{e}")
def start_evaluation(self):
threading.Thread(target=self.evaluate_essay).start()
def evaluate_essay(self):
if not self.image_files:
messagebox.showerror("错误", "请先导入图片文件或文件夹!")
return
self.info_var.set("正在提取内容,请稍候...")
try:
for file in self.image_files:
result = self.chat_doubao(file)
base_name = os.path.splitext(os.path.basename(file))[0]
output_path = os.path.join(self.output_dir, f"{base_name}.txt")
with open(output_path, "a+", encoding="utf-8") as f:
f.write(result)
self.info_var.set("提取完成!")
except Exception as e:
messagebox.showerror("错误", f"提取失败: {e}")
self.info_var.set("提取失败,请重试")
def get_order(self):
with open("order.txt","r",encoding="utf-8") as f:
order = f.read().strip()
return order
def image_to_base64(self,image_path):
# 获取图片文件的MIME类型
ext = os.path.splitext(image_path)[1].lower()
mime_type = f"image/{ext[1:]}" if ext in ['.jpg', '.jpeg', '.png', '.gif'] else "image/jpeg"
with open(image_path, "rb") as image_file:
# 读取文件内容并进行Base64编码
base64_data = base64.b64encode(image_file.read()).decode('utf-8')
# 返回完整的data URI格式
return f"data:{mime_type};base64,{base64_data}"
def chat_doubao(self,local_image_path):
# 初始化客户端
client = OpenAI(
base_url="https://ark.cn-beijing.volces.com/api/v3",
api_key="" # 这里要输入自己的API
)
try:
# 转换本地图片为Base64编码
image_data = self.image_to_base64(local_image_path)
# 调用API处理图片
response = client.chat.completions.create(
model="doubao-seed-1-6-250615",
messages=[
{
"role": "user",
"content": [
{
"type": "image_url",
"image_url": {
"url": image_data # 使用Base64编码的本地图片数据
},
},
{"type": "text", "text": self.get_order()},
],
}
]
)
# 提取并打印内容
content = response.choices[0].message.content
self.text_display.insert(END, f"{content}\n")
self.text_display.see(END)
# 更新预览图片显示
self.display_image(local_image_path)
# 更新顶部路径栏显示
self.image_path_entry.delete(0, END)
self.image_path_entry.insert(0, local_image_path)
except FileNotFoundError:
self.text_display.insert('1.0',f"错误:找不到图片文件 '{local_image_path}'")
except Exception as e:
print(f"处理过程中发生错误:{str(e)}")
return content
def open_output_dir(self):
os.startfile(self.output_dir)
if __name__ == "__main__":
root = Tk()
app = ImageEssayEvaluator(root)
root.mainloop()
四、源码下载
批量图片信息提取_pythonfun作品.zip
(4.89 KB, 下载次数: 58)
2025-8-8 17:24 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB