搞了搞Python,写了个图片对比程序及AI硅基流动对话
图片对比(查重图片)
import tkinter as tk
from tkinter import filedialog, messagebox
from PIL import Image, ImageTk
from docx import Document
import io
import zipfile
import xml.etree.ElementTree as ET
import xxhash
from concurrent.futures import ThreadPoolExecutor
same_images = [] # 存储相同图片的信息
current_index = 0 # 当前显示的图片索引
def extract_images_with_positions(docx_file):
doc = Document(docx_file)
images = []
with zipfile.ZipFile(docx_file) as z:
with z.open('word/document.xml') as f:
xml_content = f.read()
root = ET.fromstring(xml_content)
namespace = {
'w': 'http://schemas.openxmlformats.org/wordprocessingml/2006/main',
'a': 'http://schemas.openxmlformats.org/drawingml/2006/main',
'r': 'http://schemas.openxmlformats.org/officeDocument/2006/relationships'
}
for i, para in enumerate(root.findall('.//w:p', namespace)):
for drawing in para.findall('.//w:drawing', namespace):
blip = drawing.find('.//a:blip', namespace)
if blip is not None:
rId = blip.attrib.get('{http://schemas.openxmlformats.org/officeDocument/2006/relationships}embed')
if rId:
img_data = doc.part.related_parts[rId].blob
page_number = (i // 10) + 1
images.append({
"data": img_data,
"position": f"段落 {i + 1}",
"page": f"第 {page_number} 页"
})
return images
def image_hash(image_data):
return xxhash.xxh64(image_data).hexdigest()
def compare_images(docx1, docx2):
with ThreadPoolExecutor() as executor:
future1 = executor.submit(extract_images_with_positions, docx1)
future2 = executor.submit(extract_images_with_positions, docx2)
images1 = future1.result()
images2 = future2.result()
same_images = []
hash_cache = {}
for img1 in images1:
if img1["data"] not in hash_cache:
hash_cache[img1["data"]] = image_hash(img1["data"])
hash1 = hash_cache[img1["data"]]
for img2 in images2:
if img2["data"] not in hash_cache:
hash_cache[img2["data"]] = image_hash(img2["data"])
hash2 = hash_cache[img2["data"]]
if hash1 == hash2:
same_images.append({
"image1_data": img1["data"],
"image1_position": img1["position"],
"image1_page": img1["page"],
"image2_data": img2["data"],
"image2_position": img2["position"],
"image2_page": img2["page"]
})
break
return same_images
def open_file(entry):
file_path = filedialog.askopenfilename(filetypes=[("Word files", "*.docx")])
entry.delete(0, tk.END)
entry.insert(0, file_path)
def clear_display():
label_img1.config(image=None)
label_img1.image = None
label_img2.config(image=None)
label_img2.image = None
label_position1.config(text="")
label_position2.config(text="")
page_label.config(text="")
def show_images(index):
if not same_images:
return
image_info = same_images[index]
img1 = Image.open(io.BytesIO(image_info["image1_data"]))
img1 = img1.resize((250, 250), Image.ANTIALIAS)
img1_tk = ImageTk.PhotoImage(img1)
label_img1.config(image=img1_tk)
label_img1.image = img1_tk
img2 = Image.open(io.BytesIO(image_info["image2_data"]))
img2 = img2.resize((250, 250), Image.ANTIALIAS)
img2_tk = ImageTk.PhotoImage(img2)
label_img2.config(image=img2_tk)
label_img2.image = img2_tk
label_position1.config(text=f"文件1位置: {image_info['image1_position']} ({image_info['image1_page']})")
label_position2.config(text=f"文件2位置: {image_info['image2_position']} ({image_info['image2_page']})")
page_label.config(text=f"第 {index + 1} 张 / 共 {len(same_images)} 张")
def show_enlarged_image(image_data):
img = Image.open(io.BytesIO(image_data))
img_tk = ImageTk.PhotoImage(img)
enlarge_window = tk.Toplevel()
enlarge_window.title("放大图片")
label_enlarged = tk.Label(enlarge_window, image=img_tk)
label_enlarged.pack()
label_enlarged.image = img_tk
def next_image():
global current_index
if current_index < len(same_images) - 1:
current_index += 1
show_images(current_index)
def prev_image():
global current_index
if current_index > 0:
current_index -= 1
show_images(current_index)
def compare_button_click():
global same_images, current_index
file1 = entry_file1.get()
file2 = entry_file2.get()
if not file1 or not file2:
messagebox.showwarning("警告", "请选择两个DOCX文件")
return
clear_display()
same_images = compare_images(file1, file2)
current_index = 0
if not same_images:
result_label.config(text="没有找到相同的图片")
else:
result_label.config(text=f"找到 {len(same_images)} 张相同的图片")
show_images(current_index)
root = tk.Tk()
root.title("DOCX图片对比工具")
frame_files = tk.Frame(root)
frame_files.pack(pady=10)
label_file1 = tk.Label(frame_files, text="文件1:")
label_file1.grid(row=0, column=0, padx=5, pady=5)
entry_file1 = tk.Entry(frame_files, width=40)
entry_file1.grid(row=0, column=1, padx=5, pady=5)
button_file1 = tk.Button(frame_files, text="选择文件", command=lambda: open_file(entry_file1))
button_file1.grid(row=0, column=2, padx=5, pady=5)
label_file2 = tk.Label(frame_files, text="文件2:")
label_file2.grid(row=1, column=0, padx=5, pady=5)
entry_file2 = tk.Entry(frame_files, width=40)
entry_file2.grid(row=1, column=1, padx=5, pady=5)
button_file2 = tk.Button(frame_files, text="选择文件", command=lambda: open_file(entry_file2))
button_file2.grid(row=1, column=2, padx=5, pady=5)
compare_button = tk.Button(root, text="对比图片", command=compare_button_click)
compare_button.pack(pady=10)
result_label = tk.Label(root, text="")
result_label.pack(pady=10)
frame_images = tk.Frame(root)
frame_images.pack(pady=10)
frame_image1 = tk.Frame(frame_images)
frame_image1.grid(row=0, column=0, padx=10)
label_img1 = tk.Label(frame_image1, text="文件1图片")
label_img1.pack()
label_position1 = tk.Label(frame_image1, text="")
label_position1.pack()
frame_image2 = tk.Frame(frame_images)
frame_image2.grid(row=0, column=1, padx=10)
label_img2 = tk.Label(frame_image2, text="文件2图片")
label_img2.pack()
label_position2 = tk.Label(frame_image2, text="")
label_position2.pack()
frame_navigation = tk.Frame(root)
frame_navigation.pack(pady=10)
prev_button = tk.Button(frame_navigation, text="上一张", command=prev_image)
prev_button.grid(row=0, column=0, padx=5)
next_button = tk.Button(frame_navigation, text="下一张", command=next_image)
next_button.grid(row=0, column=1, padx=5)
page_label = tk.Label(root, text="")
page_label.pack(pady=10)
root.mainloop()
AI聊天
import tkinter as tk
from tkinter import scrolledtext, ttk
import requests
import threading
API_URL = "https://api.siliconflow.cn/v1/chat/completions"
API_KEY = "sk-kqfjwpreepqitvsvhpipjvnscnxqadsuomiaaflkmmxsghps" # 替换为你的 API Key
root = tk.Tk()
root.title("硅基流动 AI 聊天框")
root.geometry("600x700")
chat_box = scrolledtext.ScrolledText(root, wrap=tk.WORD, state='disabled', font=("Arial", 12))
chat_box.pack(padx=10, pady=10, fill=tk.BOTH, expand=True)
input_frame = tk.Frame(root)
input_frame.pack(padx=10, pady=10, fill=tk.X)
model_label = tk.Label(input_frame, text="模型名称:", font=("Arial", 12))
model_label.pack(side=tk.LEFT, padx=(0, 10))
model_var = tk.StringVar(value="Qwen/Qwen2.5-7B-Instruct") # 默认模型名称
model_entry = tk.Entry(input_frame, textvariable=model_var, width=20, font=("Arial", 12))
model_entry.pack(side=tk.LEFT, padx=(0, 10))
user_input = tk.Entry(input_frame, width=30, font=("Arial", 12))
user_input.pack(side=tk.LEFT, fill=tk.X, expand=True)
send_button = tk.Button(input_frame, text="发送", command=lambda: send_message(), font=("Arial", 12))
send_button.pack(side=tk.RIGHT, padx=(10, 0))
params_frame = tk.Frame(root)
params_frame.pack(padx=10, pady=10, fill=tk.X)
max_tokens_label = tk.Label(params_frame, text="max_tokens:", font=("Arial", 12))
max_tokens_label.pack(side=tk.LEFT, padx=(0, 10))
max_tokens_var = tk.IntVar(value=512)
max_tokens_entry = tk.Entry(params_frame, textvariable=max_tokens_var, width=10, font=("Arial", 12))
max_tokens_entry.pack(side=tk.LEFT, padx=(0, 10))
temperature_label = tk.Label(params_frame, text="temperature:", font=("Arial", 12))
temperature_label.pack(side=tk.LEFT, padx=(0, 10))
temperature_var = tk.DoubleVar(value=0.7)
temperature_entry = tk.Entry(params_frame, textvariable=temperature_var, width=10, font=("Arial", 12))
temperature_entry.pack(side=tk.LEFT, padx=(0, 10))
def display_message(sender, message):
chat_box.config(state='normal')
chat_box.insert(tk.END, f"{sender}: {message}\n\n")
chat_box.config(state='disabled')
chat_box.yview(tk.END)
def send_message():
message = user_input.get().strip()
if not message:
return
display_message("你", message)
user_input.delete(0, tk.END)
selected_model = model_var.get()
max_tokens = max_tokens_var.get()
temperature = temperature_var.get()
threading.Thread(target=fetch_ai_response, args=(selected_model, message, max_tokens, temperature)).start()
def fetch_ai_response(model, message, max_tokens, temperature):
try:
headers = {
"Content-Type": "application/json",
"Authorization": f"Bearer {API_KEY}"
}
data = {
"model": model, # 动态传入模型名称
"messages": [{"role": "user", "content": message}],
"stream": False,
"max_tokens": max_tokens,
"temperature": temperature,
"top_p": 0.7,
"top_k": 50,
"frequency_penalty": 0.5,
"response_format": {"type": "text"}
}
print("Sending request to:", API_URL)
print("Headers:", headers)
print("Body:", data)
response = requests.post(API_URL, headers=headers, json=data)
response.raise_for_status()
result = response.json()
print("Received response:", result)
ai_response = result.get("choices", [{}])[0].get("message", {}).get("content", "抱歉,我暂时无法处理你的请求。")
display_message("AI", ai_response)
except requests.exceptions.HTTPError as e:
print(f"HTTP Error: {e}")
print(f"Response content: {e.response.text}")
display_message("AI", "抱歉,我暂时无法处理你的请求。")
except Exception as e:
print(f"Error fetching AI response: {e}")
display_message("AI", "抱歉,我暂时无法处理你的请求。")
root.bind('<Return>', lambda event: send_message())
root.mainloop()