ImageCorpForAD / app.py
dseditor's picture
Upload 2 files
4616fe0 verified
raw
history blame
5.66 kB
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
)