显示具体的模板尺寸

This commit is contained in:
puke
2025-11-03 11:38:11 +08:00
parent 4dbf08ca5a
commit 20e210b88d
4 changed files with 160 additions and 33 deletions

View File

@@ -4,7 +4,8 @@ Template utility functions for size parsing and template management
import os import os
from pathlib import Path from pathlib import Path
from typing import List, Tuple, Optional from typing import List, Tuple, Optional, Literal
from pydantic import BaseModel, Field
def parse_template_size(template_path: str) -> Tuple[int, int]: def parse_template_size(template_path: str) -> Tuple[int, int]:
@@ -154,6 +155,113 @@ def get_template_full_path(size: str, template_name: str) -> str:
return str(template_path) return str(template_path)
class TemplateDisplayInfo(BaseModel):
"""Template display information for UI layer"""
name: str = Field(..., description="Template name without extension")
size: str = Field(..., description="Size string like '1080x1920'")
width: int = Field(..., description="Width in pixels")
height: int = Field(..., description="Height in pixels")
orientation: Literal['portrait', 'landscape', 'square'] = Field(
...,
description="Video orientation"
)
is_standard: bool = Field(
...,
description="True only for standard sizes: 1080x1920, 1920x1080, 1080x1080"
)
class TemplateInfo(BaseModel):
"""Complete template information with path and display info"""
template_path: str = Field(..., description="Full template path like '1080x1920/default.html'")
display_info: TemplateDisplayInfo = Field(..., description="Display information")
def format_template_display_info(template_name: str, size: str) -> TemplateDisplayInfo:
"""
Format template display information for UI
Returns structured data for UI layer to handle display and i18n.
Args:
template_name: Template filename like "default.html"
size: Size string like "1080x1920"
Returns:
TemplateDisplayInfo object with name, size, dimensions, orientation, and standard flag
Examples:
>>> info = format_template_display_info("default.html", "1080x1920")
>>> info.name
'default'
>>> info.is_standard
True
>>> info = format_template_display_info("custom.html", "1080x1921")
>>> info.orientation
'portrait'
>>> info.is_standard
False
"""
# Keep full template name with .html extension
name = template_name
# Parse size
width, height = map(int, size.split('x'))
# Detect orientation
if height > width:
orientation = 'portrait'
elif width > height:
orientation = 'landscape'
else:
orientation = 'square'
# Check if it's a standard size (only these three)
is_standard = (width, height) in [(1080, 1920), (1920, 1080), (1080, 1080)]
return TemplateDisplayInfo(
name=name,
size=size,
width=width,
height=height,
orientation=orientation,
is_standard=is_standard
)
def get_all_templates_with_info() -> List[TemplateInfo]:
"""
Get all templates with their display information
Returns:
List of TemplateInfo objects
Example:
>>> templates = get_all_templates_with_info()
>>> for t in templates:
... print(f"{t.display_info.name} - {t.display_info.orientation}")
... print(f" Path: {t.template_path}")
... print(f" Standard: {t.display_info.is_standard}")
"""
result = []
sizes = list_available_sizes()
for size in sizes:
templates = list_templates_for_size(size)
for template in templates:
display_info = format_template_display_info(template, size)
full_path = f"{size}/{template}"
result.append(TemplateInfo(
template_path=full_path,
display_info=display_info
))
return result
def resolve_template_path(template_input: Optional[str]) -> str: def resolve_template_path(template_input: Optional[str]) -> str:
""" """
Resolve template input to full path with validation Resolve template input to full path with validation

View File

@@ -667,47 +667,52 @@ def main():
st.markdown(tr("template.how")) st.markdown(tr("template.how"))
# Import template utilities # Import template utilities
from pixelle_video.utils.template_util import list_available_sizes, list_templates_for_size from pixelle_video.utils.template_util import get_all_templates_with_info
# Step 1: Select video size # Get all templates with their info
VIDEO_SIZE_OPTIONS = { all_templates = get_all_templates_with_info()
"📱 竖屏视频 (1080×1920)": "1080x1920",
"🖥 横屏视频 (1920×1080)": "1920x1080",
"⬜ 方形视频 (1080×1080)": "1080x1080",
}
# Filter available sizes (only show sizes that exist) if not all_templates:
available_sizes = list_available_sizes() st.error("No templates found. Please ensure templates are in templates/ directory with proper structure (e.g., templates/1080x1920/default.html).")
available_size_options = {k: v for k, v in VIDEO_SIZE_OPTIONS.items() if v in available_sizes}
if not available_size_options:
st.error("No template sizes found. Please ensure templates are in correct directory structure.")
st.stop() st.stop()
selected_size_label = st.selectbox( # Build display names with i18n
tr("template.video_size"), ORIENTATION_I18N = {
list(available_size_options.keys()), 'portrait': tr('orientation.portrait'),
label_visibility="collapsed" 'landscape': tr('orientation.landscape'),
) 'square': tr('orientation.square')
selected_size = available_size_options[selected_size_label] }
# Step 2: Select template for the chosen size display_options = {}
template_files = list_templates_for_size(selected_size) for item in all_templates:
info = item.display_info
name = info.name
orientation = ORIENTATION_I18N.get(info.orientation, info.orientation)
# Default to default.html if exists, otherwise first option # Always show dimensions for standardization
default_template_index = 0 display_name = f"{name} - {orientation}{info.width}×{info.height}"
if "default.html" in template_files:
default_template_index = template_files.index("default.html")
template_name = st.selectbox( display_options[display_name] = item.template_path
tr("template.style"),
template_files if template_files else ["default.html"], # Default to "default" portrait if exists
index=default_template_index, display_names = list(display_options.keys())
label_visibility="collapsed" default_index = 0
for idx, name in enumerate(display_names):
if "default" in name.lower() and tr('orientation.portrait') in name:
default_index = idx
break
# Single dropdown with formatted names
selected_display_name = st.selectbox(
tr("template.select"),
display_names,
index=default_index,
label_visibility="collapsed",
help=tr("template.select_help")
) )
# Combine size and template name to get full path # Get full template path
frame_template = f"{selected_size}/{template_name}" frame_template = display_options[selected_display_name]
# Template preview expander # Template preview expander
with st.expander(tr("template.preview_title"), expanded=False): with st.expander(tr("template.preview_title"), expanded=False):

View File

@@ -66,11 +66,18 @@
"style.generated_prompt": "Generated prompt: {prompt}", "style.generated_prompt": "Generated prompt: {prompt}",
"template.selector": "Template Selection", "template.selector": "Template Selection",
"template.select": "Select Template",
"template.select_help": "Select template and video size",
"template.default": "Default", "template.default": "Default",
"template.modern": "Modern", "template.modern": "Modern",
"template.neon": "Neon", "template.neon": "Neon",
"template.what": "Controls the visual layout and design style of each frame (title, text, image arrangement)", "template.what": "Controls the visual layout and design style of each frame (title, text, image arrangement)",
"template.how": "Place .html template files in the templates/ folder for automatic detection. Supports custom CSS styles", "template.how": "Place .html template files in the templates/ folder for automatic detection. Supports custom CSS styles",
"template.size_info": "Template Size",
"orientation.portrait": "Portrait",
"orientation.landscape": "Landscape",
"orientation.square": "Square",
"template.preview_title": "Preview Template", "template.preview_title": "Preview Template",
"template.preview_param_title": "Title", "template.preview_param_title": "Title",
"template.preview_param_text": "Text", "template.preview_param_text": "Text",

View File

@@ -66,11 +66,18 @@
"style.generated_prompt": "生成的提示词:{prompt}", "style.generated_prompt": "生成的提示词:{prompt}",
"template.selector": "模板选择", "template.selector": "模板选择",
"template.select": "选择模板",
"template.select_help": "选择模板和视频尺寸",
"template.default": "默认", "template.default": "默认",
"template.modern": "现代", "template.modern": "现代",
"template.neon": "霓虹", "template.neon": "霓虹",
"template.what": "控制视频每一帧的视觉布局和设计风格(标题、文本、图片的排版样式)", "template.what": "控制视频每一帧的视觉布局和设计风格(标题、文本、图片的排版样式)",
"template.how": "将 .html 模板文件放入 templates/ 文件夹即可自动识别。支持自定义 CSS 样式", "template.how": "将 .html 模板文件放入 templates/ 文件夹即可自动识别。支持自定义 CSS 样式",
"template.size_info": "模板尺寸",
"orientation.portrait": "竖屏",
"orientation.landscape": "横屏",
"orientation.square": "方形",
"template.preview_title": "预览模板", "template.preview_title": "预览模板",
"template.preview_param_title": "标题", "template.preview_param_title": "标题",
"template.preview_param_text": "文本", "template.preview_param_text": "文本",