diff --git a/requirements.txt b/requirements.txt index dad7ee0e1..f05003796 100644 --- a/requirements.txt +++ b/requirements.txt @@ -26,3 +26,4 @@ pystray==0.19.4 ruamel.yaml==0.17.22 platformdirs==3.11.0 rapidocr-onnxruntime==1.3.7 +crossclip==0.2.2 diff --git a/server.py b/server.py index 6db45cf3a..9791c70b5 100755 --- a/server.py +++ b/server.py @@ -16,6 +16,7 @@ import webview import os +import io import multiprocessing from threading import Thread import json @@ -33,6 +34,8 @@ import tkinter from tkinter import messagebox +from crossclip.clipboard import Clipboard +from PIL import Image mimetypes.add_type("text/html", ".html") @@ -229,7 +232,7 @@ def open_folder_dialog(): return "" -@app.route("/dialog/save/img", methods=["POST"]) +@app.route("/dialog/save-img", methods=["POST"]) @require_token def save_file_dialog(): img = request.files["img"] @@ -258,6 +261,17 @@ def save_file_dialog(): return f"图片已导出至{img_path}" +@app.route("/copy-img", methods=["POST"]) +@require_token +def copy_img_to_clipboard(): + img = request.files["img"] + if not img: + return "图片未上传" + cb = Clipboard() + cb.set_image(Image.open(io.BytesIO(img.read()))) + return "已复制到剪切板" + + @app.route("/check-maa") @require_token def get_maa_adb_version(): diff --git a/ui/src/pages/Plan.vue b/ui/src/pages/Plan.vue index f479ae1a7..cfac32bfc 100644 --- a/ui/src/pages/Plan.vue +++ b/ui/src/pages/Plan.vue @@ -43,7 +43,7 @@ const generating_image = ref(false) const message = useMessage() const loading = ref(null) -async function save() { +async function screenshot() { generating_image.value = true loading.value = message.loading('正在生成图片……', { duration: 0 }) if ( @@ -56,9 +56,28 @@ async function save() { const blob = await toBlob(plan_editor.value.outer, { pixelRatio: 3, backgroundColor: 'white' }) loading.value.destroy() generating_image.value = false + return blob +} + +async function save() { + const blob = await screenshot() + const form_data = new FormData() + form_data.append('img', blob) + const resp = await axios.post( + `${import.meta.env.VITE_HTTP_URL}/dialog/save-img`, + form_data + ) + message.info(resp.data) +} + +async function copy() { + const blob = await screenshot() const form_data = new FormData() form_data.append('img', blob) - const resp = await axios.post(`${import.meta.env.VITE_HTTP_URL}/dialog/save/img`, form_data) + const resp = await axios.post( + `${import.meta.env.VITE_HTTP_URL}/copy-img`, + form_data + ) message.info(resp.data) } @@ -76,7 +95,10 @@ async function save() {