Spaces:
Runtime error
Runtime error
charSLee013 commited on
Commit ·
e105e80
1
Parent(s): 12814f4
first commit
Browse files- .gitignore +198 -0
- app.py +0 -0
- config.py +64 -0
- examples/anime_input/example1.jpg +3 -0
- examples/five_view_input/example1.jpg +3 -0
- examples/interior_input.png +3 -0
- examples/line_art_input/example1.jpg +3 -0
- examples/line_art_input/example2.jpg +3 -0
- examples/line_art_input/example3.jpg +3 -0
- examples/outpainting_input/example1.jpg +3 -0
- examples/outpainting_input/example2.jpg +3 -0
- examples/outpainting_input/example3.jpg +3 -0
- examples/real_input/example1.jpg +3 -0
- examples/real_input/example2.jpg +3 -0
- examples/real_input/example3.jpg +3 -0
- examples/results/abstract_buildings.jpg +3 -0
- examples/results/anime_to_real_example1.jpg +3 -0
- examples/results/cat_windowsill.jpg +3 -0
- examples/results/chinese_woman_guqin.jpg +3 -0
- examples/results/cyberpunk_city.jpg +3 -0
- examples/results/deep_sea_creatures.jpg +3 -0
- examples/results/fairy_forest.jpg +3 -0
- examples/results/five_view_example1.jpg +3 -0
- examples/results/floating_castle.jpg +3 -0
- examples/results/interior_italian_luxury.jpg +3 -0
- examples/results/interior_japanese_wabi_sabi.jpg +3 -0
- examples/results/interior_nordic_cozy.jpg +3 -0
- examples/results/interior_parisian_apartment.jpg +3 -0
- examples/results/japanese_garden.jpg +3 -0
- examples/results/line_art_example1.jpg +3 -0
- examples/results/line_art_example2.jpg +3 -0
- examples/results/line_art_example3.jpg +3 -0
- examples/results/mountain_lake.jpg +3 -0
- examples/results/outpainting_example1.jpg +3 -0
- examples/results/outpainting_example2.jpg +3 -0
- examples/results/outpainting_example3.jpg +3 -0
- examples/results/real_to_anime_example1.jpg +3 -0
- examples/results/real_to_anime_example2.jpg +3 -0
- examples/results/real_to_anime_example3.jpg +3 -0
- examples/results/steampunk_robot.jpg +3 -0
- examples/results/tiger_jungle.jpg +3 -0
- examples/results/vaporwave_sunset.jpg +3 -0
- examples_config.py +502 -0
- models.py +200 -0
- requirements.txt +6 -0
.gitignore
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# 环境配置文件
|
| 2 |
+
.env
|
| 3 |
+
.env.local
|
| 4 |
+
.env.*.local
|
| 5 |
+
|
| 6 |
+
# Python
|
| 7 |
+
__pycache__/
|
| 8 |
+
*.py[cod]
|
| 9 |
+
*$py.class
|
| 10 |
+
*.so
|
| 11 |
+
.Python
|
| 12 |
+
build/
|
| 13 |
+
develop-eggs/
|
| 14 |
+
dist/
|
| 15 |
+
downloads/
|
| 16 |
+
eggs/
|
| 17 |
+
.eggs/
|
| 18 |
+
lib/
|
| 19 |
+
lib64/
|
| 20 |
+
parts/
|
| 21 |
+
sdist/
|
| 22 |
+
var/
|
| 23 |
+
wheels/
|
| 24 |
+
pip-wheel-metadata/
|
| 25 |
+
share/python-wheels/
|
| 26 |
+
*.egg-info/
|
| 27 |
+
.installed.cfg
|
| 28 |
+
*.egg
|
| 29 |
+
MANIFEST
|
| 30 |
+
|
| 31 |
+
# PyInstaller
|
| 32 |
+
*.manifest
|
| 33 |
+
*.spec
|
| 34 |
+
|
| 35 |
+
# Installer logs
|
| 36 |
+
pip-log.txt
|
| 37 |
+
pip-delete-this-directory.txt
|
| 38 |
+
|
| 39 |
+
# Unit test / coverage reports
|
| 40 |
+
htmlcov/
|
| 41 |
+
.tox/
|
| 42 |
+
.nox/
|
| 43 |
+
.coverage
|
| 44 |
+
.coverage.*
|
| 45 |
+
.cache
|
| 46 |
+
nosetests.xml
|
| 47 |
+
coverage.xml
|
| 48 |
+
*.cover
|
| 49 |
+
*.py,cover
|
| 50 |
+
.hypothesis/
|
| 51 |
+
.pytest_cache/
|
| 52 |
+
|
| 53 |
+
# Translations
|
| 54 |
+
*.mo
|
| 55 |
+
*.pot
|
| 56 |
+
|
| 57 |
+
# Django stuff:
|
| 58 |
+
*.log
|
| 59 |
+
local_settings.py
|
| 60 |
+
db.sqlite3
|
| 61 |
+
db.sqlite3-journal
|
| 62 |
+
|
| 63 |
+
# Flask stuff:
|
| 64 |
+
instance/
|
| 65 |
+
.webassets-cache
|
| 66 |
+
|
| 67 |
+
# Scrapy stuff:
|
| 68 |
+
.scrapy
|
| 69 |
+
|
| 70 |
+
# Sphinx documentation
|
| 71 |
+
docs/_build/
|
| 72 |
+
|
| 73 |
+
# PyBuilder
|
| 74 |
+
target/
|
| 75 |
+
|
| 76 |
+
# Jupyter Notebook
|
| 77 |
+
.ipynb_checkpoints
|
| 78 |
+
|
| 79 |
+
# IPython
|
| 80 |
+
profile_default/
|
| 81 |
+
ipython_config.py
|
| 82 |
+
|
| 83 |
+
# pyenv
|
| 84 |
+
.python-version
|
| 85 |
+
|
| 86 |
+
# pipenv
|
| 87 |
+
Pipfile.lock
|
| 88 |
+
|
| 89 |
+
# PEP 582
|
| 90 |
+
__pypackages__/
|
| 91 |
+
|
| 92 |
+
# Celery stuff
|
| 93 |
+
celerybeat-schedule
|
| 94 |
+
celerybeat.pid
|
| 95 |
+
|
| 96 |
+
# SageMath parsed files
|
| 97 |
+
*.sage.py
|
| 98 |
+
|
| 99 |
+
# Environments
|
| 100 |
+
.venv
|
| 101 |
+
env/
|
| 102 |
+
venv/
|
| 103 |
+
ENV/
|
| 104 |
+
env.bak/
|
| 105 |
+
venv.bak/
|
| 106 |
+
|
| 107 |
+
# Spyder project settings
|
| 108 |
+
.spyderproject
|
| 109 |
+
.spyproject
|
| 110 |
+
|
| 111 |
+
# Rope project settings
|
| 112 |
+
.ropeproject
|
| 113 |
+
|
| 114 |
+
# mkdocs documentation
|
| 115 |
+
/site
|
| 116 |
+
|
| 117 |
+
# mypy
|
| 118 |
+
.mypy_cache/
|
| 119 |
+
.dmypy.json
|
| 120 |
+
dmypy.json
|
| 121 |
+
|
| 122 |
+
# Pyre type checker
|
| 123 |
+
.pyre/
|
| 124 |
+
|
| 125 |
+
# IDEs
|
| 126 |
+
.vscode/
|
| 127 |
+
.idea/
|
| 128 |
+
*.swp
|
| 129 |
+
*.swo
|
| 130 |
+
*~
|
| 131 |
+
|
| 132 |
+
# OS
|
| 133 |
+
.DS_Store
|
| 134 |
+
.DS_Store?
|
| 135 |
+
._*
|
| 136 |
+
.Spotlight-V100
|
| 137 |
+
.Trashes
|
| 138 |
+
ehthumbs.db
|
| 139 |
+
Thumbs.db
|
| 140 |
+
|
| 141 |
+
# 数据库文件
|
| 142 |
+
*.db
|
| 143 |
+
*.sqlite
|
| 144 |
+
*.sqlite3
|
| 145 |
+
|
| 146 |
+
# 日志文件
|
| 147 |
+
*.log
|
| 148 |
+
logs/
|
| 149 |
+
|
| 150 |
+
# 临时文件
|
| 151 |
+
tmp/
|
| 152 |
+
temp/
|
| 153 |
+
*.tmp
|
| 154 |
+
|
| 155 |
+
# SSL证书文件
|
| 156 |
+
*.pem
|
| 157 |
+
*.crt
|
| 158 |
+
*.key
|
| 159 |
+
|
| 160 |
+
# 敏感信息目录
|
| 161 |
+
secrets/
|
| 162 |
+
|
| 163 |
+
# 上传文件
|
| 164 |
+
uploads/
|
| 165 |
+
static/uploads/
|
| 166 |
+
|
| 167 |
+
# 临时调试文件和脚本
|
| 168 |
+
debug_*.py
|
| 169 |
+
test_*_fix.py
|
| 170 |
+
test_*_cache*.py
|
| 171 |
+
simple_cache_test.py
|
| 172 |
+
*_debug_report_*.md
|
| 173 |
+
fix_*.py
|
| 174 |
+
*_investigation.py
|
| 175 |
+
*_diagnosis.py
|
| 176 |
+
*_debug_temp.py
|
| 177 |
+
trace_*.py
|
| 178 |
+
temp_*.py
|
| 179 |
+
|
| 180 |
+
# 临时脚本和报告
|
| 181 |
+
security_audit_report.txt
|
| 182 |
+
gradio_debug_report_*.md
|
| 183 |
+
backend_test_results.json
|
| 184 |
+
final_validation_summary.py
|
| 185 |
+
*.investigation
|
| 186 |
+
*.diagnosis
|
| 187 |
+
|
| 188 |
+
# 但保留项目中的重要测试文件
|
| 189 |
+
!tests/
|
| 190 |
+
!fastapi-backend/tests/
|
| 191 |
+
!**/test_*.py
|
| 192 |
+
!simple_gradio_app.py
|
| 193 |
+
!verify_*.py
|
| 194 |
+
!check_*.py
|
| 195 |
+
|
| 196 |
+
# Gradio cache and generated files
|
| 197 |
+
.gradio/
|
| 198 |
+
gradio_cached_examples/
|
app.py
ADDED
|
The diff for this file is too large to render.
See raw diff
|
|
|
config.py
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import os
|
| 2 |
+
from typing import Final
|
| 3 |
+
from pydantic import BaseModel, Field
|
| 4 |
+
|
| 5 |
+
from dotenv import load_dotenv
|
| 6 |
+
load_dotenv()
|
| 7 |
+
|
| 8 |
+
class AppConfig(BaseModel):
|
| 9 |
+
API_BASE_URL: str = Field(default=os.getenv("API_BASE_URL", "http://localhost:8000"), description="Backend API base URL")
|
| 10 |
+
API_AUTH_TOKEN: str = Field(default=os.getenv("API_AUTH_TOKEN", ""), description="API authentication token - REQUIRED")
|
| 11 |
+
API_TIMEOUT: int = Field(default=int(os.getenv("API_TIMEOUT", "120")), description="API request timeout in seconds")
|
| 12 |
+
|
| 13 |
+
def model_post_init(self, __context) -> None:
|
| 14 |
+
|
| 15 |
+
if not self.API_AUTH_TOKEN:
|
| 16 |
+
raise ValueError("❌ API_AUTH_TOKEN 环境变量必须设置")
|
| 17 |
+
|
| 18 |
+
# 简化的禁用令牌检查
|
| 19 |
+
forbidden_tokens = {
|
| 20 |
+
"",
|
| 21 |
+
"your_secret_token_here",
|
| 22 |
+
"your_api_token_here"
|
| 23 |
+
}
|
| 24 |
+
|
| 25 |
+
if self.API_AUTH_TOKEN in forbidden_tokens:
|
| 26 |
+
raise ValueError(f"❌ 禁止使用占位符令牌: {self.API_AUTH_TOKEN}")
|
| 27 |
+
|
| 28 |
+
# 简化:只要求基本长度
|
| 29 |
+
if len(self.API_AUTH_TOKEN) < 8:
|
| 30 |
+
raise ValueError("❌ 认证令牌长度必须至少8字符")
|
| 31 |
+
|
| 32 |
+
# Polling Configuration
|
| 33 |
+
POLL_INTERVAL: float = Field(default=3.0, description="Status polling interval in seconds")
|
| 34 |
+
MAX_POLL_ATTEMPTS: int = Field(default=900, description="Maximum polling attempts (45 minutes for new workflow)")
|
| 35 |
+
|
| 36 |
+
# UI Configuration
|
| 37 |
+
APP_TITLE: str = Field(default="AI Image Generator", description="Application title")
|
| 38 |
+
APP_DESCRIPTION: str = Field(default="Robust AI image generation with clean state management", description="App description")
|
| 39 |
+
|
| 40 |
+
# Server Configuration
|
| 41 |
+
SERVER_PORT: int = Field(default=int(os.getenv("SERVER_PORT", "7860")), description="Server port")
|
| 42 |
+
ENABLE_SHARE: bool = Field(default=os.getenv("ENABLE_SHARE", "false").lower() == "true", description="Enable Gradio sharing")
|
| 43 |
+
|
| 44 |
+
# Authentication Configuration
|
| 45 |
+
ENABLE_AUTH: bool = Field(default=os.getenv("ENABLE_AUTH", "false").lower() == "true", description="Enable authentication")
|
| 46 |
+
AUTH_USERNAME: str = Field(default=os.getenv("AUTH_USERNAME", "admin"), description="Authentication username")
|
| 47 |
+
AUTH_PASSWORD: str = Field(default=os.getenv("AUTH_PASSWORD", "password"), description="Authentication password")
|
| 48 |
+
|
| 49 |
+
# Logging Configuration
|
| 50 |
+
LOG_LEVEL: str = Field(default="WARNING", description="Logging level")
|
| 51 |
+
ENABLE_DEBUG_LOGGING: bool = Field(default=False, description="Enable detailed debug logging")
|
| 52 |
+
|
| 53 |
+
CONFIG: Final[AppConfig] = AppConfig()
|
| 54 |
+
|
| 55 |
+
def get_api_headers() -> dict[str, str]:
|
| 56 |
+
|
| 57 |
+
return {
|
| 58 |
+
"Content-Type": "application/json",
|
| 59 |
+
"X-API-Auth": CONFIG.API_AUTH_TOKEN
|
| 60 |
+
}
|
| 61 |
+
|
| 62 |
+
def get_api_url(endpoint: str) -> str:
|
| 63 |
+
|
| 64 |
+
return f"{CONFIG.API_BASE_URL.rstrip('/')}/{endpoint.lstrip('/')}"
|
examples/anime_input/example1.jpg
ADDED
|
Git LFS Details
|
examples/five_view_input/example1.jpg
ADDED
|
Git LFS Details
|
examples/interior_input.png
ADDED
|
Git LFS Details
|
examples/line_art_input/example1.jpg
ADDED
|
Git LFS Details
|
examples/line_art_input/example2.jpg
ADDED
|
Git LFS Details
|
examples/line_art_input/example3.jpg
ADDED
|
Git LFS Details
|
examples/outpainting_input/example1.jpg
ADDED
|
Git LFS Details
|
examples/outpainting_input/example2.jpg
ADDED
|
Git LFS Details
|
examples/outpainting_input/example3.jpg
ADDED
|
Git LFS Details
|
examples/real_input/example1.jpg
ADDED
|
Git LFS Details
|
examples/real_input/example2.jpg
ADDED
|
Git LFS Details
|
examples/real_input/example3.jpg
ADDED
|
Git LFS Details
|
examples/results/abstract_buildings.jpg
ADDED
|
Git LFS Details
|
examples/results/anime_to_real_example1.jpg
ADDED
|
Git LFS Details
|
examples/results/cat_windowsill.jpg
ADDED
|
Git LFS Details
|
examples/results/chinese_woman_guqin.jpg
ADDED
|
Git LFS Details
|
examples/results/cyberpunk_city.jpg
ADDED
|
Git LFS Details
|
examples/results/deep_sea_creatures.jpg
ADDED
|
Git LFS Details
|
examples/results/fairy_forest.jpg
ADDED
|
Git LFS Details
|
examples/results/five_view_example1.jpg
ADDED
|
Git LFS Details
|
examples/results/floating_castle.jpg
ADDED
|
Git LFS Details
|
examples/results/interior_italian_luxury.jpg
ADDED
|
Git LFS Details
|
examples/results/interior_japanese_wabi_sabi.jpg
ADDED
|
Git LFS Details
|
examples/results/interior_nordic_cozy.jpg
ADDED
|
Git LFS Details
|
examples/results/interior_parisian_apartment.jpg
ADDED
|
Git LFS Details
|
examples/results/japanese_garden.jpg
ADDED
|
Git LFS Details
|
examples/results/line_art_example1.jpg
ADDED
|
Git LFS Details
|
examples/results/line_art_example2.jpg
ADDED
|
Git LFS Details
|
examples/results/line_art_example3.jpg
ADDED
|
Git LFS Details
|
examples/results/mountain_lake.jpg
ADDED
|
Git LFS Details
|
examples/results/outpainting_example1.jpg
ADDED
|
Git LFS Details
|
examples/results/outpainting_example2.jpg
ADDED
|
Git LFS Details
|
examples/results/outpainting_example3.jpg
ADDED
|
Git LFS Details
|
examples/results/real_to_anime_example1.jpg
ADDED
|
Git LFS Details
|
examples/results/real_to_anime_example2.jpg
ADDED
|
Git LFS Details
|
examples/results/real_to_anime_example3.jpg
ADDED
|
Git LFS Details
|
examples/results/steampunk_robot.jpg
ADDED
|
Git LFS Details
|
examples/results/tiger_jungle.jpg
ADDED
|
Git LFS Details
|
examples/results/vaporwave_sunset.jpg
ADDED
|
Git LFS Details
|
examples_config.py
ADDED
|
@@ -0,0 +1,502 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
TEXT_TO_IMAGE_EXAMPLES = [
|
| 2 |
+
["An orange cat sitting on a windowsill, sunlight streaming through the window onto it, cozy home environment, high-definition photography"],
|
| 3 |
+
["A majestic tiger walking through the jungle, sharp eyes, clear fur details, wildlife photography"],
|
| 4 |
+
["Futuristic tech city at night, neon lights flashing, flying cars shuttling through the air, cyberpunk style, 4K quality"],
|
| 5 |
+
["Steampunk-style robot, intricate gears and steam, retro industrial design, metallic texture"],
|
| 6 |
+
["Beautiful woman in traditional Chinese clothing playing guqin in bamboo forest, elegant atmosphere, Chinese painting style, fine brushwork"],
|
| 7 |
+
["Japanese garden with cherry blossoms falling, ancient wooden buildings, stone lanterns, zen aesthetics, spring"],
|
| 8 |
+
["A castle floating in the clouds, surrounded by rainbows and flying birds, dreamy fairy tale style, Disney animation"],
|
| 9 |
+
["Fairy in magical forest, glowing wings, mysterious mushroom house, fantasy illustration style"],
|
| 10 |
+
|
| 11 |
+
# Natural Landscape
|
| 12 |
+
["Peaceful lake reflecting snow-capped mountains, sunrise moment, golden sunlight on water surface, landscape photography"],
|
| 13 |
+
["Mysterious creatures in the deep sea, glowing jellyfish and coral, blue dreamy lighting, ocean wonder"],
|
| 14 |
+
|
| 15 |
+
# Artistic Creative
|
| 16 |
+
["Abstract art style city buildings, geometric combinations, vibrant color contrasts, modern art"],
|
| 17 |
+
["Vaporwave aesthetic sunset, pink-purple tones, retro grid background, 80s nostalgia"]
|
| 18 |
+
]
|
| 19 |
+
|
| 20 |
+
TEXT_TO_IMAGE_EXAMPLES_WITH_RESULTS = [
|
| 21 |
+
# 格式: [提示词, 分辨率, 图片文件路径]
|
| 22 |
+
# Animals
|
| 23 |
+
[
|
| 24 |
+
"An orange cat sitting on a windowsill, sunlight streaming through the window onto it, cozy home environment, high-definition photography",
|
| 25 |
+
"square - 1024x1024 (1:1)",
|
| 26 |
+
"examples/results/cat_windowsill.jpg"
|
| 27 |
+
],
|
| 28 |
+
[
|
| 29 |
+
"A majestic tiger walking through the jungle, sharp eyes, clear fur details, wildlife photography",
|
| 30 |
+
"landscape - 1152x896 (4:3)",
|
| 31 |
+
"examples/results/tiger_jungle.jpg"
|
| 32 |
+
],
|
| 33 |
+
|
| 34 |
+
# Sci-fi Future
|
| 35 |
+
[
|
| 36 |
+
"Futuristic tech city at night, neon lights flashing, flying cars shuttling through the air, cyberpunk style, 4K quality",
|
| 37 |
+
"landscape - 1344x768 (16:9)",
|
| 38 |
+
"examples/results/cyberpunk_city.jpg"
|
| 39 |
+
],
|
| 40 |
+
[
|
| 41 |
+
"Steampunk-style robot, intricate gears and steam, retro industrial design, metallic texture",
|
| 42 |
+
"square - 1024x1024 (1:1)",
|
| 43 |
+
"examples/results/steampunk_robot.jpg"
|
| 44 |
+
],
|
| 45 |
+
|
| 46 |
+
# Traditional Oriental
|
| 47 |
+
[
|
| 48 |
+
"Beautiful woman in traditional Chinese clothing playing guqin in bamboo forest, elegant atmosphere, Chinese painting style, fine brushwork",
|
| 49 |
+
"portrait - 768x1344 (9:16)",
|
| 50 |
+
"examples/results/chinese_woman_guqin.jpg"
|
| 51 |
+
],
|
| 52 |
+
[
|
| 53 |
+
"Japanese garden with cherry blossoms falling, ancient wooden buildings, stone lanterns, zen aesthetics, spring",
|
| 54 |
+
"landscape - 1216x832 (3:2)",
|
| 55 |
+
"examples/results/japanese_garden.jpg"
|
| 56 |
+
],
|
| 57 |
+
|
| 58 |
+
# Fantasy Fairy Tale
|
| 59 |
+
[
|
| 60 |
+
"A castle floating in the clouds, surrounded by rainbows and flying birds, dreamy fairy tale style, Disney animation",
|
| 61 |
+
"landscape - 1152x896 (4:3)",
|
| 62 |
+
"examples/results/floating_castle.jpg"
|
| 63 |
+
],
|
| 64 |
+
[
|
| 65 |
+
"Fairy in magical forest, glowing wings, mysterious mushroom house, fantasy illustration style",
|
| 66 |
+
"square - 1024x1024 (1:1)",
|
| 67 |
+
"examples/results/fairy_forest.jpg"
|
| 68 |
+
],
|
| 69 |
+
|
| 70 |
+
# Natural Landscape
|
| 71 |
+
[
|
| 72 |
+
"Peaceful lake reflecting snow-capped mountains, sunrise moment, golden sunlight on water surface, landscape photography",
|
| 73 |
+
"landscape - 1344x768 (16:9)",
|
| 74 |
+
"examples/results/mountain_lake.jpg"
|
| 75 |
+
],
|
| 76 |
+
[
|
| 77 |
+
"Mysterious creatures in the deep sea, glowing jellyfish and coral, blue dreamy lighting, ocean wonder",
|
| 78 |
+
"portrait - 896x1152 (3:4)",
|
| 79 |
+
"examples/results/deep_sea_creatures.jpg"
|
| 80 |
+
],
|
| 81 |
+
|
| 82 |
+
# Artistic Creative
|
| 83 |
+
[
|
| 84 |
+
"Abstract art style city buildings, geometric combinations, vibrant color contrasts, modern art",
|
| 85 |
+
"square - 1024x1024 (1:1)",
|
| 86 |
+
"examples/results/abstract_buildings.jpg"
|
| 87 |
+
],
|
| 88 |
+
[
|
| 89 |
+
"Vaporwave aesthetic sunset, pink-purple tones, retro grid background, 80s nostalgia",
|
| 90 |
+
"landscape - 1536x640 (21:9)",
|
| 91 |
+
"examples/results/vaporwave_sunset.jpg"
|
| 92 |
+
]
|
| 93 |
+
]
|
| 94 |
+
|
| 95 |
+
# 文生图示例标签(可选,用于更好的用户体验)
|
| 96 |
+
TEXT_TO_IMAGE_LABELS = [
|
| 97 |
+
"🐱 Cozy Cat",
|
| 98 |
+
"🐅 Wild Tiger",
|
| 99 |
+
"🌃 Cyberpunk City",
|
| 100 |
+
"🤖 Steampunk Robot",
|
| 101 |
+
"🎵 Elegant Guqin Lady",
|
| 102 |
+
"🌸 Japanese Sakura Garden",
|
| 103 |
+
"🏰 Castle in the Clouds",
|
| 104 |
+
"🧚 Forest Fairy",
|
| 105 |
+
"🏔️ Sunrise over Snowy Lake",
|
| 106 |
+
"🌊 Deep Sea Wonders",
|
| 107 |
+
"🏙️ Abstract Architecture",
|
| 108 |
+
"🌅 Vaporwave Sunset"
|
| 109 |
+
]
|
| 110 |
+
|
| 111 |
+
# 按类别组织的示例(用于高级展示)
|
| 112 |
+
CATEGORIZED_EXAMPLES = {
|
| 113 |
+
"🐾 Animal World": [
|
| 114 |
+
["An orange cat sitting on a windowsill, sunlight streaming through the window onto it, cozy home environment, high-definition photography"],
|
| 115 |
+
["A majestic tiger walking through the jungle, sharp eyes, clear fur details, wildlife photography"],
|
| 116 |
+
["An elegant white swan swimming on the lake, feathers white as snow, clear reflection, nature photography"]
|
| 117 |
+
],
|
| 118 |
+
|
| 119 |
+
"🚀 Sci-Fi Future": [
|
| 120 |
+
["Futuristic tech city at night, neon lights flashing, flying cars shuttling through the air, cyberpunk style, 4K quality"],
|
| 121 |
+
["Steampunk-style robot, intricate gears and steam, retro industrial design, metallic texture"],
|
| 122 |
+
["Inside a space station, astronauts floating in zero gravity, sci-fi movie scene, high-tech equipment"]
|
| 123 |
+
],
|
| 124 |
+
|
| 125 |
+
"🏮 Traditional Aesthetics": [
|
| 126 |
+
["Beautiful woman in traditional Chinese clothing playing guqin in bamboo forest, elegant atmosphere, Chinese painting style, fine brushwork"],
|
| 127 |
+
["Japanese garden with cherry blossoms falling, ancient wooden buildings, stone lanterns, zen aesthetics, spring"],
|
| 128 |
+
["Traditional Chinese architecture complex, flying eaves, red walls and yellow tiles, architectural photography"]
|
| 129 |
+
],
|
| 130 |
+
|
| 131 |
+
"✨ Fantasy Magic": [
|
| 132 |
+
["A castle floating in the clouds, surrounded by rainbows and flying birds, dreamy fairy tale style, Disney animation"],
|
| 133 |
+
["Fairy in magical forest, glowing wings, mysterious mushroom house, fantasy illustration style"],
|
| 134 |
+
["Dragon hovering over mountain peaks, breathing fire, epic fantasy scene, cinematic quality"]
|
| 135 |
+
],
|
| 136 |
+
|
| 137 |
+
"🌄 Natural Landscape": [
|
| 138 |
+
["Peaceful lake reflecting snow-capped mountains, sunrise moment, golden sunlight on water surface, landscape photography"],
|
| 139 |
+
["Mysterious creatures in the deep sea, glowing jellyfish and coral, blue dreamy lighting, ocean wonder"],
|
| 140 |
+
["Autumn maple forest with red and yellow leaves, sunlight filtering through leaves, warm tones"]
|
| 141 |
+
]
|
| 142 |
+
}
|
| 143 |
+
|
| 144 |
+
# 图生图基本信息
|
| 145 |
+
IMAGE_TO_IMAGE_INFO = {
|
| 146 |
+
"supported_formats": ["PNG", "JPEG", "BMP", "WEBP"],
|
| 147 |
+
"file_size_limit": "10MB"
|
| 148 |
+
}
|
| 149 |
+
|
| 150 |
+
# 摄影风格转换基本信息
|
| 151 |
+
PHOTO_STYLE_INFO = {
|
| 152 |
+
"supported_formats": ["PNG", "JPEG", "BMP", "WEBP"],
|
| 153 |
+
"file_size_limit": "10MB",
|
| 154 |
+
"max_resolution": "2000x2000",
|
| 155 |
+
"min_resolution": "500x500",
|
| 156 |
+
"auto_resize": True,
|
| 157 |
+
"description": "Transform your photos with professional photography styles"
|
| 158 |
+
}
|
| 159 |
+
|
| 160 |
+
# 摄影风格列表和描述
|
| 161 |
+
PHOTO_STYLES = [
|
| 162 |
+
"Photo-Camera Movement", # 移动镜头
|
| 163 |
+
"Photo-Relighting", # 重新布光
|
| 164 |
+
"Photo-Camera Zoom", # 画面缩放
|
| 165 |
+
"Photo-Professional Product Photography", # 专业产品图
|
| 166 |
+
"Photo-Tilt-Shift Miniature", # 微缩世界
|
| 167 |
+
"Photo-Reflection Addition", # 添加倒影
|
| 168 |
+
"Photo-Character Pose & Viewpoint Change" # 角色姿势视角变换
|
| 169 |
+
]
|
| 170 |
+
|
| 171 |
+
PHOTO_STYLE_DESCRIPTIONS = {
|
| 172 |
+
"Photo-Camera Movement": {
|
| 173 |
+
"name": "Camera Movement",
|
| 174 |
+
"description": "Create dynamic camera motion effects to enhance movement and visual impact",
|
| 175 |
+
"effect": "Best for sports scenes, street photography, dynamic portraits",
|
| 176 |
+
"example": "Turn static photos into motion trail and motion blur effects"
|
| 177 |
+
},
|
| 178 |
+
"Photo-Relighting": {
|
| 179 |
+
"name": "Relighting",
|
| 180 |
+
"description": "Modify the lighting and atmosphere of the photo, optimizing light and shadow relationships",
|
| 181 |
+
"effect": "Great for portrait, indoor scenes, and product photography",
|
| 182 |
+
"example": "Adjust light direction, intensity, and color temperature to create different visual moods"
|
| 183 |
+
},
|
| 184 |
+
"Photo-Camera Zoom": {
|
| 185 |
+
"name": "Camera Zoom",
|
| 186 |
+
"description": "Adjust zoom and focus effects to highlight the subject or change perspective",
|
| 187 |
+
"effect": "Suitable for landscapes, architecture, and close-ups",
|
| 188 |
+
"example": "Create telephoto compression or wide-angle perspective effects"
|
| 189 |
+
},
|
| 190 |
+
"Photo-Professional Product Photography": {
|
| 191 |
+
"name": "Professional Product Photography",
|
| 192 |
+
"description": "Convert to professional product photography style, highlighting product features",
|
| 193 |
+
"effect": "Ideal for e-commerce, industrial design, and showcases",
|
| 194 |
+
"example": "Optimize lighting, background, and composition to increase commercial value"
|
| 195 |
+
},
|
| 196 |
+
"Photo-Tilt-Shift Miniature": {
|
| 197 |
+
"name": "Tilt-Shift Miniature",
|
| 198 |
+
"description": "Create a miniature model-like effect for a whimsical atmosphere",
|
| 199 |
+
"effect": "Works well for cityscapes, building clusters, and top-down shots",
|
| 200 |
+
"example": "Use selective focus and color tuning to make real scenes look like models"
|
| 201 |
+
},
|
| 202 |
+
"Photo-Reflection Addition": {
|
| 203 |
+
"name": "Reflection Addition",
|
| 204 |
+
"description": "Add natural reflections to images to enhance visual layering",
|
| 205 |
+
"effect": "Good for water surfaces, glass, and mirror effects",
|
| 206 |
+
"example": "Add realistic reflections on water, ground, or other reflective surfaces"
|
| 207 |
+
},
|
| 208 |
+
"Photo-Character Pose & Viewpoint Change": {
|
| 209 |
+
"name": "Pose & Viewpoint Change",
|
| 210 |
+
"description": "Change human pose and shooting angle to create new compositions",
|
| 211 |
+
"effect": "Useful for portrait, fashion, and artistic photography",
|
| 212 |
+
"example": "Adjust body movements, expressions, and camera angle for better visual results"
|
| 213 |
+
}
|
| 214 |
+
}
|
| 215 |
+
|
| 216 |
+
# 摄影风格转换示例配置
|
| 217 |
+
PHOTO_STYLE_EXAMPLES = [
|
| 218 |
+
{
|
| 219 |
+
"style": "Photo-Camera Movement",
|
| 220 |
+
"description": "Add dynamic camera movement to static portraits",
|
| 221 |
+
"tags": ["dynamic", "motion", "street"]
|
| 222 |
+
},
|
| 223 |
+
{
|
| 224 |
+
"style": "Photo-Relighting",
|
| 225 |
+
"description": "Optimize lighting for indoor portraits",
|
| 226 |
+
"tags": ["portrait", "lighting", "ambience"]
|
| 227 |
+
},
|
| 228 |
+
{
|
| 229 |
+
"style": "Photo-Camera Zoom",
|
| 230 |
+
"description": "Adjust focal length effects for landscape photos",
|
| 231 |
+
"tags": ["landscape", "focal", "perspective"]
|
| 232 |
+
},
|
| 233 |
+
{
|
| 234 |
+
"style": "Photo-Professional Product Photography",
|
| 235 |
+
"description": "Convert regular product photos into professional commercial shots",
|
| 236 |
+
"tags": ["product", "commercial", "e-commerce"]
|
| 237 |
+
},
|
| 238 |
+
{
|
| 239 |
+
"style": "Photo-Tilt-Shift Miniature",
|
| 240 |
+
"description": "Turn cityscapes into miniature model effects",
|
| 241 |
+
"tags": ["miniature", "whimsical", "creative"]
|
| 242 |
+
},
|
| 243 |
+
{
|
| 244 |
+
"style": "Photo-Reflection Addition",
|
| 245 |
+
"description": "Add water reflections to architecture photos",
|
| 246 |
+
"tags": ["reflection", "water", "symmetry"]
|
| 247 |
+
},
|
| 248 |
+
{
|
| 249 |
+
"style": "Photo-Character Pose & Viewpoint Change",
|
| 250 |
+
"description": "Adjust pose and viewpoint for portrait photography",
|
| 251 |
+
"tags": ["portrait", "pose", "viewpoint"]
|
| 252 |
+
}
|
| 253 |
+
]
|
| 254 |
+
|
| 255 |
+
# 获取随机示例(用于动态展示)
|
| 256 |
+
def get_random_examples(category=None, count=4):
|
| 257 |
+
|
| 258 |
+
import random
|
| 259 |
+
|
| 260 |
+
if category and category in CATEGORIZED_EXAMPLES:
|
| 261 |
+
examples = CATEGORIZED_EXAMPLES[category]
|
| 262 |
+
else:
|
| 263 |
+
examples = TEXT_TO_IMAGE_EXAMPLES
|
| 264 |
+
|
| 265 |
+
if len(examples) <= count:
|
| 266 |
+
return examples
|
| 267 |
+
|
| 268 |
+
return random.sample(examples, count)
|
| 269 |
+
|
| 270 |
+
# 获取分类示例(用于标签页展示)
|
| 271 |
+
def get_categorized_examples():
|
| 272 |
+
|
| 273 |
+
return CATEGORIZED_EXAMPLES
|
| 274 |
+
|
| 275 |
+
# 室内设计渲染示例配置
|
| 276 |
+
|
| 277 |
+
# 室内设计渲染示例配置(重新实现)
|
| 278 |
+
|
| 279 |
+
INTERIOR_DESIGN_EXAMPLES_WITH_RESULTS = [
|
| 280 |
+
[
|
| 281 |
+
"examples/interior_input.png", # 输入的白膜图
|
| 282 |
+
"japanese_wabi_sabi", # 日本诧寂风格
|
| 283 |
+
"examples/results/interior_japanese_wabi_sabi.jpg" # 渲染结果
|
| 284 |
+
],
|
| 285 |
+
[
|
| 286 |
+
"examples/interior_input.png", # 输入的白膜图
|
| 287 |
+
"nordic_cozy", # 北欧温馨风格
|
| 288 |
+
"examples/results/interior_nordic_cozy.jpg" # 渲染结果
|
| 289 |
+
],
|
| 290 |
+
[
|
| 291 |
+
"examples/interior_input.png", # 输入的白膜图
|
| 292 |
+
"italian_luxury", # 意大利风格
|
| 293 |
+
"examples/results/interior_italian_luxury.jpg" # 渲染结果
|
| 294 |
+
],
|
| 295 |
+
[
|
| 296 |
+
"examples/interior_input.png", # 输入的白膜图
|
| 297 |
+
"parisian_apartment", # 巴黎套间风格
|
| 298 |
+
"examples/results/interior_parisian_apartment.jpg" # 渲染结果
|
| 299 |
+
]
|
| 300 |
+
]
|
| 301 |
+
|
| 302 |
+
# 摄影风格转换相关辅助函数
|
| 303 |
+
def get_photo_styles():
|
| 304 |
+
|
| 305 |
+
return PHOTO_STYLES.copy()
|
| 306 |
+
|
| 307 |
+
def get_photo_style_description(style):
|
| 308 |
+
|
| 309 |
+
return PHOTO_STYLE_DESCRIPTIONS.get(style)
|
| 310 |
+
|
| 311 |
+
def get_photo_style_info():
|
| 312 |
+
|
| 313 |
+
return PHOTO_STYLE_INFO.copy()
|
| 314 |
+
|
| 315 |
+
def get_photo_style_examples():
|
| 316 |
+
|
| 317 |
+
return PHOTO_STYLE_EXAMPLES.copy()
|
| 318 |
+
|
| 319 |
+
def validate_photo_style(style):
|
| 320 |
+
|
| 321 |
+
return style in PHOTO_STYLES
|
| 322 |
+
|
| 323 |
+
def get_photo_styles_with_descriptions():
|
| 324 |
+
|
| 325 |
+
return PHOTO_STYLE_DESCRIPTIONS.copy()
|
| 326 |
+
|
| 327 |
+
def get_random_photo_style_examples(count=3):
|
| 328 |
+
|
| 329 |
+
import random
|
| 330 |
+
|
| 331 |
+
if len(PHOTO_STYLE_EXAMPLES) <= count:
|
| 332 |
+
return PHOTO_STYLE_EXAMPLES.copy()
|
| 333 |
+
|
| 334 |
+
return random.sample(PHOTO_STYLE_EXAMPLES, count)
|
| 335 |
+
|
| 336 |
+
# 线稿转换示例配置
|
| 337 |
+
|
| 338 |
+
# 线稿转换基本信息
|
| 339 |
+
LINE_ART_CONVERSION_INFO = {
|
| 340 |
+
"supported_formats": ["PNG", "JPEG", "BMP", "WEBP"],
|
| 341 |
+
"file_size_limit": "10MB",
|
| 342 |
+
"max_resolution": "2000x2000",
|
| 343 |
+
"min_resolution": "500x500",
|
| 344 |
+
"auto_resize": True,
|
| 345 |
+
"description": "Convert your photos into clean line art drawings"
|
| 346 |
+
}
|
| 347 |
+
|
| 348 |
+
# 线稿转换示例配置(简化格式,只包含输入和输出)
|
| 349 |
+
# 格式: [输入图片路径, 结果图片路径]
|
| 350 |
+
LINE_ART_CONVERSION_EXAMPLES_WITH_RESULTS = [
|
| 351 |
+
[
|
| 352 |
+
"examples/line_art_input/example1.jpg", # 输入图片
|
| 353 |
+
"examples/results/line_art_example1.jpg" # 结果图片
|
| 354 |
+
],
|
| 355 |
+
[
|
| 356 |
+
"examples/line_art_input/example2.jpg", # 输入图片
|
| 357 |
+
"examples/results/line_art_example2.jpg" # 结果图片
|
| 358 |
+
],
|
| 359 |
+
[
|
| 360 |
+
"examples/line_art_input/example3.jpg", # 输入图片
|
| 361 |
+
"examples/results/line_art_example3.jpg" # 结果图片
|
| 362 |
+
]
|
| 363 |
+
]
|
| 364 |
+
|
| 365 |
+
# 线稿转换相关辅助函数
|
| 366 |
+
def get_line_art_conversion_info():
|
| 367 |
+
|
| 368 |
+
return LINE_ART_CONVERSION_INFO.copy()
|
| 369 |
+
|
| 370 |
+
def get_line_art_conversion_examples():
|
| 371 |
+
|
| 372 |
+
return LINE_ART_CONVERSION_EXAMPLES_WITH_RESULTS.copy()
|
| 373 |
+
|
| 374 |
+
# 二次元转真人相关配置
|
| 375 |
+
ANIME_TO_REAL_INFO = {
|
| 376 |
+
"description": "Convert anime illustrations into realistic photos",
|
| 377 |
+
"supported_formats": ["PNG", "JPEG", "JPG", "WEBP"],
|
| 378 |
+
"max_file_size": "10MB",
|
| 379 |
+
"recommended_resolution": "512x512 to 1024x1024",
|
| 380 |
+
"processing_time": "Typically 1–3 minutes"
|
| 381 |
+
}
|
| 382 |
+
|
| 383 |
+
# 二次元转真人示例配置
|
| 384 |
+
|
| 385 |
+
ANIME_TO_REAL_EXAMPLES_WITH_RESULTS = [
|
| 386 |
+
["examples/anime_input/example1.jpg","examples/results/anime_to_real_example1.jpg"]
|
| 387 |
+
]
|
| 388 |
+
|
| 389 |
+
# 用于显示预生成结果的映射(如果需要)
|
| 390 |
+
ANIME_TO_REAL_RESULTS_MAP = {
|
| 391 |
+
"examples/anime_input/example1.jpg": "examples/results/anime_to_real_example1.jpg"
|
| 392 |
+
}
|
| 393 |
+
|
| 394 |
+
# 二次元转真人相关辅助函数
|
| 395 |
+
def get_anime_to_real_info():
|
| 396 |
+
|
| 397 |
+
return ANIME_TO_REAL_INFO.copy()
|
| 398 |
+
|
| 399 |
+
def get_anime_to_real_examples():
|
| 400 |
+
|
| 401 |
+
return ANIME_TO_REAL_EXAMPLES_WITH_RESULTS.copy()
|
| 402 |
+
|
| 403 |
+
def get_random_line_art_examples(count=3):
|
| 404 |
+
|
| 405 |
+
import random
|
| 406 |
+
|
| 407 |
+
if len(LINE_ART_CONVERSION_EXAMPLES_WITH_RESULTS) <= count:
|
| 408 |
+
return LINE_ART_CONVERSION_EXAMPLES_WITH_RESULTS.copy()
|
| 409 |
+
|
| 410 |
+
return random.sample(LINE_ART_CONVERSION_EXAMPLES_WITH_RESULTS, count)
|
| 411 |
+
|
| 412 |
+
# 真实图片转动漫插画相关配置
|
| 413 |
+
REAL_TO_ANIME_INFO = {
|
| 414 |
+
"description": "Convert real photos into anime illustration style",
|
| 415 |
+
"supported_formats": ["PNG", "JPEG", "JPG", "WEBP"],
|
| 416 |
+
"max_file_size": "10MB",
|
| 417 |
+
"recommended_resolution": "512x512 to 1024x1024",
|
| 418 |
+
"processing_time": "Typically 1–3 minutes"
|
| 419 |
+
}
|
| 420 |
+
|
| 421 |
+
# 真实图片转动漫示例配置
|
| 422 |
+
# 格式: [输入图片路径, 结果图片路径]
|
| 423 |
+
REAL_TO_ANIME_EXAMPLES_WITH_RESULTS = [
|
| 424 |
+
["examples/real_input/example1.jpg", "examples/results/real_to_anime_example1.jpg"],
|
| 425 |
+
["examples/real_input/example2.jpg", "examples/results/real_to_anime_example2.jpg"],
|
| 426 |
+
["examples/real_input/example3.jpg", "examples/results/real_to_anime_example3.jpg"]
|
| 427 |
+
]
|
| 428 |
+
|
| 429 |
+
# 用于显示预生成结果的映射(如果需要)
|
| 430 |
+
REAL_TO_ANIME_RESULTS_MAP = {
|
| 431 |
+
"examples/real_input/example1.jpg": "examples/results/real_to_anime_example1.jpg",
|
| 432 |
+
"examples/real_input/example2.jpg": "examples/results/real_to_anime_example2.jpg",
|
| 433 |
+
"examples/real_input/example3.jpg": "examples/results/real_to_anime_example3.jpg"
|
| 434 |
+
}
|
| 435 |
+
|
| 436 |
+
# 真实图片转动漫相关辅助函数
|
| 437 |
+
def get_real_to_anime_info():
|
| 438 |
+
|
| 439 |
+
return REAL_TO_ANIME_INFO.copy()
|
| 440 |
+
|
| 441 |
+
def get_real_to_anime_examples():
|
| 442 |
+
|
| 443 |
+
return REAL_TO_ANIME_EXAMPLES_WITH_RESULTS.copy()
|
| 444 |
+
|
| 445 |
+
def get_random_real_to_anime_examples(count=3):
|
| 446 |
+
|
| 447 |
+
import random
|
| 448 |
+
|
| 449 |
+
if len(REAL_TO_ANIME_EXAMPLES_WITH_RESULTS) <= count:
|
| 450 |
+
return REAL_TO_ANIME_EXAMPLES_WITH_RESULTS.copy()
|
| 451 |
+
|
| 452 |
+
return random.sample(REAL_TO_ANIME_EXAMPLES_WITH_RESULTS, count)
|
| 453 |
+
|
| 454 |
+
FIVE_VIEW_GENERATION_EXAMPLES_WITH_RESULTS = [
|
| 455 |
+
# 格式: [输入图片路径, 结果图片路径]
|
| 456 |
+
[
|
| 457 |
+
"examples/five_view_input/example1.jpg",
|
| 458 |
+
"examples/results/five_view_example1.jpg"
|
| 459 |
+
]
|
| 460 |
+
]
|
| 461 |
+
|
| 462 |
+
def get_random_five_view_examples(count=1):
|
| 463 |
+
|
| 464 |
+
import random
|
| 465 |
+
|
| 466 |
+
if len(FIVE_VIEW_GENERATION_EXAMPLES_WITH_RESULTS) <= count:
|
| 467 |
+
return FIVE_VIEW_GENERATION_EXAMPLES_WITH_RESULTS.copy()
|
| 468 |
+
|
| 469 |
+
return random.sample(FIVE_VIEW_GENERATION_EXAMPLES_WITH_RESULTS, count)
|
| 470 |
+
|
| 471 |
+
# 图像扩展示例配置 - 使用多样化图片和真实AI生成的扩图结果
|
| 472 |
+
IMAGE_OUTPAINTING_EXAMPLES_WITH_RESULTS = [
|
| 473 |
+
|
| 474 |
+
[
|
| 475 |
+
"examples/outpainting_input/example1.jpg",
|
| 476 |
+
0.2, # 轻度扩展 - 原始测试图片
|
| 477 |
+
0.3, # 中等宽度扩展
|
| 478 |
+
"examples/results/outpainting_example1.jpg" # 真实AI生成结果
|
| 479 |
+
],
|
| 480 |
+
[
|
| 481 |
+
"examples/outpainting_input/example2.jpg",
|
| 482 |
+
0.2, # 轻度高度扩展 - 日式住宅,适合横向扩展
|
| 483 |
+
0.4, # 较大宽度扩展
|
| 484 |
+
"examples/results/outpainting_example2.jpg" # 待生成真实AI结果
|
| 485 |
+
],
|
| 486 |
+
[
|
| 487 |
+
"examples/outpainting_input/example3.jpg",
|
| 488 |
+
0.5, # 较大高度扩展 - 不露脸自拍,适合纵向扩展
|
| 489 |
+
0.2, # 轻度宽度扩展
|
| 490 |
+
"examples/results/outpainting_example3.jpg" # 待生成真实AI结果
|
| 491 |
+
]
|
| 492 |
+
]
|
| 493 |
+
|
| 494 |
+
def get_random_outpainting_examples(count=3):
|
| 495 |
+
|
| 496 |
+
import random
|
| 497 |
+
|
| 498 |
+
if len(IMAGE_OUTPAINTING_EXAMPLES_WITH_RESULTS) <= count:
|
| 499 |
+
return IMAGE_OUTPAINTING_EXAMPLES_WITH_RESULTS.copy()
|
| 500 |
+
|
| 501 |
+
return random.sample(IMAGE_OUTPAINTING_EXAMPLES_WITH_RESULTS, count)
|
| 502 |
+
|
models.py
ADDED
|
@@ -0,0 +1,200 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from enum import Enum
|
| 2 |
+
from typing import Optional, Any
|
| 3 |
+
from datetime import datetime
|
| 4 |
+
from pydantic import BaseModel, Field, validator
|
| 5 |
+
import uuid
|
| 6 |
+
|
| 7 |
+
class TaskStatus(str, Enum):
|
| 8 |
+
|
| 9 |
+
QUEUED = "queued"
|
| 10 |
+
PROCESSING = "processing"
|
| 11 |
+
COMPLETED = "completed"
|
| 12 |
+
FAILED = "failed"
|
| 13 |
+
CANCELLED = "cancelled"
|
| 14 |
+
|
| 15 |
+
class UIState(str, Enum):
|
| 16 |
+
|
| 17 |
+
IDLE = "idle"
|
| 18 |
+
SUBMITTING = "submitting"
|
| 19 |
+
QUEUED = "queued"
|
| 20 |
+
PROCESSING = "processing"
|
| 21 |
+
COMPLETED = "completed"
|
| 22 |
+
ERROR = "error"
|
| 23 |
+
|
| 24 |
+
class TaskInfo(BaseModel):
|
| 25 |
+
|
| 26 |
+
task_id: str = Field(..., description="Unique task identifier")
|
| 27 |
+
status: TaskStatus = Field(..., description="Current task status")
|
| 28 |
+
position: int = Field(default=0, description="Queue position")
|
| 29 |
+
message: str = Field(default="", description="Status message")
|
| 30 |
+
result_url: Optional[str] = Field(default=None, description="Result image URL")
|
| 31 |
+
error_message: Optional[str] = Field(default=None, description="Error message if failed")
|
| 32 |
+
|
| 33 |
+
@validator('task_id')
|
| 34 |
+
def validate_task_id(cls, v):
|
| 35 |
+
|
| 36 |
+
try:
|
| 37 |
+
uuid.UUID(v)
|
| 38 |
+
return v
|
| 39 |
+
except ValueError:
|
| 40 |
+
raise ValueError(f"Invalid task ID format: {v}")
|
| 41 |
+
|
| 42 |
+
class Config:
|
| 43 |
+
frozen = True # Immutable
|
| 44 |
+
|
| 45 |
+
class UIStateInfo(BaseModel):
|
| 46 |
+
|
| 47 |
+
state: UIState = Field(..., description="Current UI state")
|
| 48 |
+
task_id: Optional[str] = Field(default=None, description="Associated task ID")
|
| 49 |
+
status_text: str = Field(default="", description="Display status text")
|
| 50 |
+
progress_text: str = Field(default="", description="Progress description")
|
| 51 |
+
show_image: bool = Field(default=False, description="Whether to show result image")
|
| 52 |
+
image_url: Optional[str] = Field(default=None, description="Result image URL")
|
| 53 |
+
submit_enabled: bool = Field(default=True, description="Submit button enabled")
|
| 54 |
+
cancel_enabled: bool = Field(default=False, description="Cancel button enabled")
|
| 55 |
+
timestamp: datetime = Field(default_factory=datetime.now, description="State timestamp")
|
| 56 |
+
|
| 57 |
+
class Config:
|
| 58 |
+
frozen = True # Immutable
|
| 59 |
+
|
| 60 |
+
class TaskSubmission(BaseModel):
|
| 61 |
+
|
| 62 |
+
prompt: str = Field(..., min_length=5, max_length=4096, description="Image generation prompt")
|
| 63 |
+
width: int = Field(default=1024, description="Image width")
|
| 64 |
+
height: int = Field(default=1024, description="Image height")
|
| 65 |
+
task_type: str = Field(default="text_to_image", description="Task type")
|
| 66 |
+
|
| 67 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 68 |
+
|
| 69 |
+
return {
|
| 70 |
+
"task_type": self.task_type,
|
| 71 |
+
"input_params": {
|
| 72 |
+
"prompt": self.prompt,
|
| 73 |
+
"width": self.width,
|
| 74 |
+
"height": self.height
|
| 75 |
+
}
|
| 76 |
+
}
|
| 77 |
+
|
| 78 |
+
class ImageToImageSubmission(BaseModel):
|
| 79 |
+
|
| 80 |
+
image_data: str = Field(..., description="Base64 encoded image data")
|
| 81 |
+
task_type: str = Field(default="image_to_image", description="Task type")
|
| 82 |
+
|
| 83 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 84 |
+
|
| 85 |
+
return {
|
| 86 |
+
"image_data": self.image_data
|
| 87 |
+
}
|
| 88 |
+
|
| 89 |
+
class PhotoStyleSubmission(BaseModel):
|
| 90 |
+
|
| 91 |
+
image_data: str = Field(..., description="Base64 encoded image data")
|
| 92 |
+
style_preset: str = Field(..., description="Photography style preset")
|
| 93 |
+
task_type: str = Field(default="photo_style_transfer", description="Task type")
|
| 94 |
+
|
| 95 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 96 |
+
|
| 97 |
+
return {
|
| 98 |
+
"image_data": self.image_data,
|
| 99 |
+
"style_preset": self.style_preset
|
| 100 |
+
}
|
| 101 |
+
|
| 102 |
+
class InteriorDesignRenderingSubmission(BaseModel):
|
| 103 |
+
|
| 104 |
+
image_data: str = Field(..., description="Base64 encoded white model image data")
|
| 105 |
+
design_style: str = Field(..., description="Interior design style")
|
| 106 |
+
task_type: str = Field(default="interior_design_rendering", description="Task type")
|
| 107 |
+
|
| 108 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 109 |
+
|
| 110 |
+
return {
|
| 111 |
+
"image_data": self.image_data,
|
| 112 |
+
"design_style": self.design_style
|
| 113 |
+
}
|
| 114 |
+
|
| 115 |
+
class WatermarkRemovalSubmission(BaseModel):
|
| 116 |
+
|
| 117 |
+
image_data: str = Field(..., description="Base64 encoded image data")
|
| 118 |
+
task_type: str = Field(default="watermark_removal", description="Task type")
|
| 119 |
+
|
| 120 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 121 |
+
|
| 122 |
+
return {
|
| 123 |
+
"image_data": self.image_data
|
| 124 |
+
}
|
| 125 |
+
|
| 126 |
+
class LineArtConversionSubmission(BaseModel):
|
| 127 |
+
|
| 128 |
+
image_data: str = Field(..., description="Base64 encoded image data")
|
| 129 |
+
task_type: str = Field(default="line_art_conversion", description="Task type")
|
| 130 |
+
|
| 131 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 132 |
+
|
| 133 |
+
return {
|
| 134 |
+
"image_data": self.image_data
|
| 135 |
+
}
|
| 136 |
+
|
| 137 |
+
class AnimeToRealSubmission(BaseModel):
|
| 138 |
+
|
| 139 |
+
image_data: str = Field(..., description="Base64 encoded anime image data")
|
| 140 |
+
task_type: str = Field(default="anime_to_real", description="Task type")
|
| 141 |
+
|
| 142 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 143 |
+
|
| 144 |
+
return {
|
| 145 |
+
"image_data": self.image_data
|
| 146 |
+
}
|
| 147 |
+
|
| 148 |
+
class RealToAnimeSubmission(BaseModel):
|
| 149 |
+
|
| 150 |
+
image_data: str = Field(..., description="Base64 encoded real image data")
|
| 151 |
+
task_type: str = Field(default="real_to_anime", description="Task type")
|
| 152 |
+
|
| 153 |
+
def to_api_payload(self) -> dict[str, Any]:
|
| 154 |
+
|
| 155 |
+
return {
|
| 156 |
+
"image_data": self.image_data
|
| 157 |
+
}
|
| 158 |
+
|
| 159 |
+
class AppSession(BaseModel):
|
| 160 |
+
|
| 161 |
+
session_id: str = Field(default_factory=lambda: str(uuid.uuid4()), description="Session ID")
|
| 162 |
+
current_ui_state: UIStateInfo = Field(default_factory=lambda: UIStateInfo(state=UIState.IDLE), description="Current UI state")
|
| 163 |
+
active_task_id: Optional[str] = Field(default=None, description="Currently active task ID")
|
| 164 |
+
last_submission: Optional[TaskSubmission] = Field(default=None, description="Last task submission")
|
| 165 |
+
created_at: datetime = Field(default_factory=datetime.now, description="Session creation time")
|
| 166 |
+
|
| 167 |
+
def is_active_task(self, task_id: str) -> bool:
|
| 168 |
+
|
| 169 |
+
return self.active_task_id == task_id
|
| 170 |
+
|
| 171 |
+
def can_submit_new_task(self) -> bool:
|
| 172 |
+
|
| 173 |
+
return self.current_ui_state.state in {UIState.IDLE, UIState.COMPLETED, UIState.ERROR}
|
| 174 |
+
|
| 175 |
+
class Config:
|
| 176 |
+
frozen = False # Mutable for state updates
|
| 177 |
+
|
| 178 |
+
class ImageOutpaintingSubmission(BaseModel):
|
| 179 |
+
|
| 180 |
+
image_data: str = Field(..., description="Base64编码的图片数据")
|
| 181 |
+
expand_height: float = Field(default=0.2, description="扩展高度百分比")
|
| 182 |
+
expand_width: float = Field(default=0.2, description="扩展宽度百分比")
|
| 183 |
+
|
| 184 |
+
def to_api_payload(self) -> dict:
|
| 185 |
+
|
| 186 |
+
return {
|
| 187 |
+
"image_data": self.image_data,
|
| 188 |
+
"expand_height": self.expand_height,
|
| 189 |
+
"expand_width": self.expand_width
|
| 190 |
+
}
|
| 191 |
+
|
| 192 |
+
class FiveViewGenerationSubmission(BaseModel):
|
| 193 |
+
|
| 194 |
+
image_data: str = Field(..., description="Base64编码的图片数据")
|
| 195 |
+
|
| 196 |
+
def to_api_payload(self) -> dict:
|
| 197 |
+
|
| 198 |
+
return {
|
| 199 |
+
"image_data": self.image_data
|
| 200 |
+
}
|
requirements.txt
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Gradio Frontend Requirements
|
| 2 |
+
gradio[oauth]>=4.0.0
|
| 3 |
+
httpx>=0.25.0
|
| 4 |
+
Pillow>=9.0.0
|
| 5 |
+
pydantic>=2.0.0
|
| 6 |
+
python-dotenv>=1.0.0
|