Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -6,7 +6,7 @@ import json
|
|
| 6 |
import gradio as gr
|
| 7 |
|
| 8 |
# =======================================================
|
| 9 |
-
# 🚀 Gradio 補丁
|
| 10 |
# =======================================================
|
| 11 |
try:
|
| 12 |
import gradio_client.utils
|
|
@@ -32,7 +32,7 @@ except Exception:
|
|
| 32 |
OMR_DIR = os.path.abspath("OMRChecker")
|
| 33 |
MOCK_DIR = os.path.abspath("mock_libs")
|
| 34 |
|
| 35 |
-
# 偽裝螢幕套件,防止 Headless 環境呼叫 cv2.imshow 崩潰
|
| 36 |
os.makedirs(MOCK_DIR, exist_ok=True)
|
| 37 |
with open(os.path.join(MOCK_DIR, "screeninfo.py"), "w", encoding="utf-8") as f:
|
| 38 |
f.write('class ScreenInfoError(Exception):\n pass\nclass FakeMonitor:\n width = 1920\n height = 1080\ndef get_monitors():\n return [FakeMonitor()]\n')
|
|
@@ -47,7 +47,7 @@ if not os.path.exists(OMR_DIR) or not os.path.exists(os.path.join(OMR_DIR, "main
|
|
| 47 |
subprocess.run([sys.executable, "-m", "pip", "install", "-r", req_path], check=True)
|
| 48 |
|
| 49 |
# =======================================================
|
| 50 |
-
# ⚡ 極速 Layout 渲染核心
|
| 51 |
# =======================================================
|
| 52 |
def generate_layout_preview(json_content):
|
| 53 |
if not json_content or str(json_content).strip() == "":
|
|
@@ -55,7 +55,7 @@ def generate_layout_preview(json_content):
|
|
| 55 |
|
| 56 |
current_dir = os.path.dirname(__file__)
|
| 57 |
|
| 58 |
-
# 自動尋找本地的 template 圖片
|
| 59 |
template_img_src = None
|
| 60 |
for file in os.listdir(current_dir):
|
| 61 |
if file.lower().startswith("template") and file.lower().endswith((".jpg", ".jpeg", ".png")):
|
|
@@ -75,17 +75,17 @@ def generate_layout_preview(json_content):
|
|
| 75 |
images_dir = os.path.join(job_dir, "images")
|
| 76 |
outputs_dir = os.path.join(OMR_DIR, "outputs")
|
| 77 |
|
| 78 |
-
# 重置目錄
|
| 79 |
if os.path.exists(job_dir): shutil.rmtree(job_dir)
|
| 80 |
os.makedirs(images_dir, exist_ok=True)
|
| 81 |
if os.path.exists(outputs_dir): shutil.rmtree(outputs_dir)
|
| 82 |
|
| 83 |
-
# 寫入 JSON 與 測試圖片
|
| 84 |
with open(os.path.join(OMR_DIR, "inputs", "template.json"), "w", encoding="utf-8") as f:
|
| 85 |
f.write(json_content)
|
| 86 |
shutil.copy(template_img_src, os.path.join(images_dir, "template_test.jpg"))
|
| 87 |
|
| 88 |
-
# 強制開啟最高視覺化等級
|
| 89 |
config_path = os.path.join(OMR_DIR, "config.json")
|
| 90 |
if os.path.exists(config_path):
|
| 91 |
try:
|
|
@@ -107,7 +107,7 @@ def generate_layout_preview(json_content):
|
|
| 107 |
cwd=OMR_DIR, capture_output=True, text=True, env=current_env
|
| 108 |
)
|
| 109 |
|
| 110 |
-
# 尋找畫好的圖片
|
| 111 |
generated_img = None
|
| 112 |
if os.path.exists(outputs_dir):
|
| 113 |
for root, dirs, files in os.walk(outputs_dir):
|
|
@@ -126,20 +126,33 @@ def generate_layout_preview(json_content):
|
|
| 126 |
return None, "❌ 繪製失敗。可能是 JSON 內的座標超出了圖片邊界。\n\n系統報錯日誌:\n" + (result.stderr or result.stdout)
|
| 127 |
|
| 128 |
# =======================================================
|
| 129 |
-
# 🎨 專用網頁介面 (Gradio)
|
| 130 |
# =======================================================
|
| 131 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 132 |
gr.Markdown("## 📐 OMRChecker 專屬 Layout 秒速調校工具")
|
| 133 |
-
gr.Markdown("不需等待批改,不需重新上傳圖片。直接修改下方 JSON,點擊右方按鈕,**2~3 秒內即可看見原廠引擎輸出的最新畫框圖片**。")
|
| 134 |
|
|
|
|
| 135 |
with gr.Row():
|
| 136 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 137 |
json_input = gr.Code(language="json", label="在此輸入或修改 Template JSON", lines=30)
|
| 138 |
|
| 139 |
with gr.Column(scale=1):
|
| 140 |
-
|
| 141 |
-
image_output = gr.Image(label="生成的 Layout 預覽圖 (原廠畫線)", type="filepath", interactive=False, height=600)
|
| 142 |
-
submit_btn = gr.Button("🚀 立即更新框線預覽 (只需 2 秒)", variant="primary")
|
| 143 |
|
| 144 |
with gr.Row():
|
| 145 |
log_output = gr.Textbox(label="後台執行日誌 (除錯用)", lines=4)
|
|
@@ -151,4 +164,5 @@ with gr.Blocks(title="OMR Layout 秒速測試器") as demo:
|
|
| 151 |
)
|
| 152 |
|
| 153 |
if __name__ == "__main__":
|
|
|
|
| 154 |
demo.launch(server_name="0.0.0.0", server_port=7860)
|
|
|
|
| 6 |
import gradio as gr
|
| 7 |
|
| 8 |
# =======================================================
|
| 9 |
+
# 🚀 核心修復:Gradio 官方 OpenAPI Schema 解析崩潰補丁
|
| 10 |
# =======================================================
|
| 11 |
try:
|
| 12 |
import gradio_client.utils
|
|
|
|
| 32 |
OMR_DIR = os.path.abspath("OMRChecker")
|
| 33 |
MOCK_DIR = os.path.abspath("mock_libs")
|
| 34 |
|
| 35 |
+
# 建立偽裝螢幕套件,防止 Headless 環境呼叫 cv2.imshow 崩潰
|
| 36 |
os.makedirs(MOCK_DIR, exist_ok=True)
|
| 37 |
with open(os.path.join(MOCK_DIR, "screeninfo.py"), "w", encoding="utf-8") as f:
|
| 38 |
f.write('class ScreenInfoError(Exception):\n pass\nclass FakeMonitor:\n width = 1920\n height = 1080\ndef get_monitors():\n return [FakeMonitor()]\n')
|
|
|
|
| 47 |
subprocess.run([sys.executable, "-m", "pip", "install", "-r", req_path], check=True)
|
| 48 |
|
| 49 |
# =======================================================
|
| 50 |
+
# ⚡ 極速 Layout 渲染核心 (不含批改,只需 2~3 秒)
|
| 51 |
# =======================================================
|
| 52 |
def generate_layout_preview(json_content):
|
| 53 |
if not json_content or str(json_content).strip() == "":
|
|
|
|
| 55 |
|
| 56 |
current_dir = os.path.dirname(__file__)
|
| 57 |
|
| 58 |
+
# 自動尋找本地的 template 圖片 (必須要有空白圖供對齊)
|
| 59 |
template_img_src = None
|
| 60 |
for file in os.listdir(current_dir):
|
| 61 |
if file.lower().startswith("template") and file.lower().endswith((".jpg", ".jpeg", ".png")):
|
|
|
|
| 75 |
images_dir = os.path.join(job_dir, "images")
|
| 76 |
outputs_dir = os.path.join(OMR_DIR, "outputs")
|
| 77 |
|
| 78 |
+
# 重置並建立乾淨的工作目錄
|
| 79 |
if os.path.exists(job_dir): shutil.rmtree(job_dir)
|
| 80 |
os.makedirs(images_dir, exist_ok=True)
|
| 81 |
if os.path.exists(outputs_dir): shutil.rmtree(outputs_dir)
|
| 82 |
|
| 83 |
+
# 寫入 JSON 與 複製測試用的 template 圖片
|
| 84 |
with open(os.path.join(OMR_DIR, "inputs", "template.json"), "w", encoding="utf-8") as f:
|
| 85 |
f.write(json_content)
|
| 86 |
shutil.copy(template_img_src, os.path.join(images_dir, "template_test.jpg"))
|
| 87 |
|
| 88 |
+
# 強制開啟最高視覺化等級 (保證產生實體劃線預覽圖)
|
| 89 |
config_path = os.path.join(OMR_DIR, "config.json")
|
| 90 |
if os.path.exists(config_path):
|
| 91 |
try:
|
|
|
|
| 107 |
cwd=OMR_DIR, capture_output=True, text=True, env=current_env
|
| 108 |
)
|
| 109 |
|
| 110 |
+
# 尋找畫好框線的輸出圖片
|
| 111 |
generated_img = None
|
| 112 |
if os.path.exists(outputs_dir):
|
| 113 |
for root, dirs, files in os.walk(outputs_dir):
|
|
|
|
| 126 |
return None, "❌ 繪製失敗。可能是 JSON 內的座標超出了圖片邊界。\n\n系統報錯日誌:\n" + (result.stderr or result.stdout)
|
| 127 |
|
| 128 |
# =======================================================
|
| 129 |
+
# 🎨 專用網頁介面 (Gradio) + 自訂 CSS 防止版面暴走
|
| 130 |
# =======================================================
|
| 131 |
+
# 限制 JSON 輸入框的最大高度,強制產生內部捲軸
|
| 132 |
+
custom_css = """
|
| 133 |
+
.json-container {
|
| 134 |
+
max-height: 75vh !important;
|
| 135 |
+
overflow-y: auto !important;
|
| 136 |
+
border: 1px solid #e5e7eb;
|
| 137 |
+
border-radius: 8px;
|
| 138 |
+
padding: 5px;
|
| 139 |
+
}
|
| 140 |
+
"""
|
| 141 |
+
|
| 142 |
+
with gr.Blocks(title="OMR Layout 秒速測試器", css=custom_css) as demo:
|
| 143 |
gr.Markdown("## 📐 OMRChecker 專屬 Layout 秒速調校工具")
|
|
|
|
| 144 |
|
| 145 |
+
# 💡 按鈕置頂:不需要往下滑就能一鍵測試
|
| 146 |
with gr.Row():
|
| 147 |
+
submit_btn = gr.Button("🚀 立即更新框線預覽 (只需 2 秒)", variant="primary", size="lg")
|
| 148 |
+
|
| 149 |
+
with gr.Row():
|
| 150 |
+
# 💡 套用 CSS 類別,讓過長的 JSON 在這個區塊內自己滾動
|
| 151 |
+
with gr.Column(scale=1, elem_classes="json-container"):
|
| 152 |
json_input = gr.Code(language="json", label="在此輸入或修改 Template JSON", lines=30)
|
| 153 |
|
| 154 |
with gr.Column(scale=1):
|
| 155 |
+
image_output = gr.Image(label="生成的 Layout 預覽圖 (原廠畫線)", type="filepath", interactive=False)
|
|
|
|
|
|
|
| 156 |
|
| 157 |
with gr.Row():
|
| 158 |
log_output = gr.Textbox(label="後台執行日誌 (除錯用)", lines=4)
|
|
|
|
| 164 |
)
|
| 165 |
|
| 166 |
if __name__ == "__main__":
|
| 167 |
+
# 若在雲端運行,請確保 server_name="0.0.0.0"
|
| 168 |
demo.launch(server_name="0.0.0.0", server_port=7860)
|