Spaces:
Running
Running
File size: 5,664 Bytes
4616fe0 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 |
import gradio as gr
import numpy as np
from PIL import Image
import io
import base64
def calculate_crop_box(image, target_ratio=1170/391):
"""
計算保持目標比例的最大裁切框
"""
width, height = image.size
current_ratio = width / height
if current_ratio > target_ratio:
# 圖片較寬,需要裁切寬度
new_width = int(height * target_ratio)
left = (width - new_width) // 2
top = 0
right = left + new_width
bottom = height
else:
# 圖片較高,需要裁切高度
new_height = int(width / target_ratio)
left = 0
top = (height - new_height) // 2
right = width
bottom = top + new_height
return (left, top, right, bottom)
def process_image(image, crop_data=None):
"""
處理圖片:裁切並調整為目標尺寸
"""
if image is None:
return None, "請上傳圖片"
# 如果有裁切數據,使用用戶選擇的區域
if crop_data is not None:
# Gradio 的 Image 組件在編輯模式下會返回包含裁切信息的數據
# 這裡我們處理裁切後的圖片
processed_image = image
else:
# 如果沒有裁切數據,自動計算最佳裁切區域
crop_box = calculate_crop_box(image)
processed_image = image.crop(crop_box)
# 調整為目標尺寸
target_size = (1170, 391)
final_image = processed_image.resize(target_size, Image.Resampling.LANCZOS)
return final_image, f"圖片已處理完成!尺寸:{final_image.size}"
def auto_crop_preview(image):
"""
自動裁切預覽
"""
if image is None:
return None, "請上傳圖片"
crop_box = calculate_crop_box(image)
cropped = image.crop(crop_box)
# 創建預覽圖片,顯示裁切區域
preview = image.copy()
from PIL import ImageDraw
draw = ImageDraw.Draw(preview)
# 繪製裁切框
draw.rectangle(crop_box, outline="red", width=3)
return preview, f"建議裁切區域:{crop_box}"
# 創建 Gradio 界面
with gr.Blocks(title="圖片裁切工具", theme=gr.themes.Soft()) as demo:
gr.Markdown("# 🖼️ 圖片裁切工具")
gr.Markdown("### 將任意尺寸的圖片按 1170:391 比例裁切並調整為目標尺寸")
with gr.Row():
with gr.Column(scale=1):
# 圖片上傳區域
input_image = gr.Image(
label="上傳圖片",
type="pil",
height=400
)
# 按鈕區域
with gr.Row():
preview_btn = gr.Button("🔍 預覽裁切區域", variant="secondary")
process_btn = gr.Button("✂️ 裁切並處理", variant="primary")
with gr.Column(scale=1):
# 輸出區域
output_image = gr.Image(
label="處理後圖片",
type="pil",
height=400
)
# 狀態信息
status_text = gr.Textbox(
label="狀態",
value="等待圖片上傳...",
interactive=False
)
# 預覽功能
with gr.Row():
preview_image = gr.Image(
label="裁切區域預覽(紅框顯示建議裁切區域)",
type="pil",
height=300,
visible=False
)
# 進階設置
with gr.Accordion("🔧 進階設置", open=False):
gr.Markdown("### 目標尺寸設置")
with gr.Row():
target_width = gr.Number(
label="目標寬度",
value=1170,
precision=0
)
target_height = gr.Number(
label="目標高度",
value=391,
precision=0
)
quality_slider = gr.Slider(
label="輸出品質",
minimum=1,
maximum=100,
value=95,
step=1
)
# 使用說明
with gr.Accordion("📖 使用說明", open=False):
gr.Markdown("""
### 如何使用:
1. **上傳圖片**:點擊上傳區域選擇您的圖片
2. **預覽裁切**:點擊「預覽裁切區域」查看建議的裁切區域
3. **手動編輯**:在上傳的圖片上直接拖拽選擇裁切區域
4. **處理圖片**:點擊「裁切並處理」生成最終圖片
5. **下載結果**:右鍵點擊處理後的圖片選擇「另存為」
### 功能特色:
- ✨ 自動計算最佳裁切比例
- 🎯 支援手動選擇裁切區域
- 📏 保持 1170:391 的精確比例
- 🖼️ 高品質圖片輸出
- 💾 簡單的下載流程
""")
# 事件綁定
preview_btn.click(
fn=auto_crop_preview,
inputs=[input_image],
outputs=[preview_image, status_text]
).then(
fn=lambda: gr.update(visible=True),
outputs=[preview_image]
)
process_btn.click(
fn=process_image,
inputs=[input_image],
outputs=[output_image, status_text]
)
# 當圖片上傳時自動更新狀態
input_image.change(
fn=lambda img: "圖片已上傳,可以開始處理!" if img is not None else "請上傳圖片",
inputs=[input_image],
outputs=[status_text]
)
# 啟動應用程式
if __name__ == "__main__":
demo.launch(
server_name="0.0.0.0",
server_port=7860,
share=True
) |