首页 > 其他分享 >整合版中间过程(缺进度条)

整合版中间过程(缺进度条)

时间:2024-03-31 09:04:33浏览次数:20  
标签:canvas 进度条 self 中间 width 整合 path root image

import tkinter as tk
from tkinter import filedialog, ttk
from PIL import Image, ImageTk
import requests
import base64
import os
import io
import random
import threading
import time

def encode_pil_to_base64(image):
    with io.BytesIO() as output_bytes:
        image.save(output_bytes, format="PNG")
        bytes_data = output_bytes.getvalue()
    return base64.b64encode(bytes_data).decode("utf-8")

def save_decoded_image(b64_image, folder_path, image_name):
    seq = 0
    output_path = os.path.join(folder_path, f"{image_name}.png")
    while os.path.exists(output_path):
        seq += 1
        output_path = os.path.join(folder_path, f"{image_name}({seq}).png")
    with open(output_path, 'wb') as image_file:
        image_file.write(base64.b64decode(b64_image))
    print(f"Image saved to: {output_path}")
    return output_path  # 返回保存的图片路径

class PhotoSketchGUI:
    def __init__(self, root):
        self.root = root
        self.root.title("建筑效果图转彩色手绘")
        self.root.configure(bg='black')
        self.root.state('zoomed')
        self.setup_ui()

    def setup_ui(self):
        screen_width = self.root.winfo_screenwidth()
        screen_height = self.root.winfo_screenheight()
        self.canvas_width = screen_width * 0.4
        self.canvas_height = screen_height * 0.8
        self.left_canvas_x = screen_width * 0.25 - self.canvas_width / 2
        self.right_canvas_x = screen_width * 0.75 - self.canvas_width / 2
        self.setup_buttons_and_canvas()
        self.setup_progress_bar()
        self.add_intro_labels()

    def setup_buttons_and_canvas(self):
        self.left_frame = tk.Canvas(self.root, width=self.canvas_width, height=self.canvas_height, bg='black', highlightthickness=0)
        self.left_frame.place(x=self.left_canvas_x, rely=0.5, anchor='w')
        self.left_frame.create_rectangle(2, 2, self.canvas_width-2, self.canvas_height-2, outline='white', dash=(5, 5))
        self.save_dir_btn = tk.Button(self.root, text="选择保存目录", command=self.select_save_folder, bg='darkgrey', fg='white', font=('微软雅黑', 12))
        self.save_dir_btn.place(x=self.left_canvas_x + self.canvas_width / 2, rely=0.5, anchor='center')
        self.right_frame = tk.Canvas(self.root, width=self.canvas_width, height=self.canvas_height, bg='black', highlightthickness=0)
        self.right_frame.place(x=self.right_canvas_x, rely=0.5, anchor='w')
        self.right_frame.create_rectangle(2, 2, self.canvas_width-2, self.canvas_height-2, outline='white', dash=(5, 5))

    def add_intro_labels(self):
        intro_label1 = tk.Label(self.root, text="建筑效果图转彩色手绘", bg='black', fg='white', font=('微软雅黑', 18, 'bold'))
        intro_label1.place(x=self.left_canvas_x, y=10)
        intro_label2 = tk.Label(self.root, text="使用介绍: 请在左侧框内上传一张建筑渲染图", bg='black', fg='white', font=('微软雅黑', 10))
        intro_label2.place(x=self.left_canvas_x, y=45)

    def setup_progress_bar(self):
        self.style = ttk.Style(self.root)
        self.style.theme_use('default')
        self.style.configure("White.Horizontal.TProgressbar", background='white')
        progress_width = self.right_canvas_x + self.canvas_width - self.left_canvas_x
        self.progress = ttk.Progressbar(self.root, style="White.Horizontal.TProgressbar", orient=tk.HORIZONTAL, length=progress_width, mode='determinate')
        self.progress['value'] = 0
        self.set_progress_position(self.left_canvas_x, self.canvas_height, 15)

    def set_progress_position(self, left_canvas_x, canvas_height, gap):
        progress_y = self.left_frame.winfo_y() + canvas_height + gap
        progress_width = self.right_frame.winfo_x() + self.right_frame.winfo_width() - left_canvas_x
        self.progress.place(x=left_canvas_x, y=progress_y, width=progress_width, height=20)

    def select_save_folder(self):
        self.folder_path = filedialog.askdirectory()
        if self.folder_path:
            self.save_dir_btn.config(text="选择参考图片", command=self.upload_image)

    def upload_image(self):
        filepath = filedialog.askopenfilename()
        if filepath:
            self.display_image(filepath, self.left_frame, 'image_label', self.left_canvas_x)
            # 使用线程避免阻塞GUI
            threading.Thread(target=self.call_api_for_sketch, args=(filepath,)).start()

    def display_image(self, image_path, canvas, label_attr, canvas_x):
        img = Image.open(image_path)
        img.thumbnail((canvas.winfo_width(), canvas.winfo_height()))
        img_tk = ImageTk.PhotoImage(img)
        if hasattr(self, label_attr):
            getattr(self, label_attr).configure(image=img_tk)
        else:
            setattr(self, label_attr, tk.Label(self.root, image=img_tk, bg='black'))
            getattr(self, label_attr).image = img_tk
            getattr(self, label_attr).place(x=canvas_x, rely=0.5, anchor='w')

    def call_api_for_sketch(self, image_path):
        # 模拟一些处理时间
        time.sleep(1)
        with Image.open(image_path) as img:
            encoded_image = encode_pil_to_base64(img)
        data = {
            "prompt": "<lora:CWG_archisketch_v1:1>,Building,pre sketch,masterpiece,best quality,featuring markers,(3D:0.7)",
            "negative_prompt": "blurry, lower quality, glossy finish,insufficient contrast",
            "init_images": [encoded_image],
            "steps": 30,
            "width": img.width,
            "height": img.height,
            "seed": random.randint(1, 10000000),
            "alwayson_scripts": {
                "ControlNet": {
                    "args": [
                        {
                            "enabled": "true",
                            "pixel_perfect": "true",
                            "module": "canny",
                            "model": "control_v11p_sd15_canny_fp16 [b18e0966]",
                            "weight": 1,
                            "image": encoded_image
                        },
                        {
                            "enabled": "true",
                            "pixel_perfect": "true",
                            "module": "depth",
                            "model": "control_v11f1p_sd15_depth_fp16 [4b72d323]",
                            "weight": 1,
                            "image": encoded_image
                        }
                    ]
                }
            }
        }

        url = "http://127.0.0.1:7860/sdapi/v1/txt2img"
        response = requests.post(url, json=data)

        if response.status_code == 200:
            response_json = response.json()
            # 保存到用户指定的目录并获取保存的图片路径
            saved_image_path = save_decoded_image(response_json['images'][0], self.folder_path, "sketched_image")
            # 在主线程中更新右侧画布以显示最新的生成图片
            self.root.after(0, self.display_image, saved_image_path, self.right_frame, 'generated_image_label', self.right_canvas_x)
        else:
            print("Failed to get response from API, status code:", response.status_code)

if __name__ == "__main__":
    root = tk.Tk()
    app = PhotoSketchGUI(root)
    root.mainloop()

 

标签:canvas,进度条,self,中间,width,整合,path,root,image
From: https://www.cnblogs.com/zly324/p/18106345

相关文章