diff --git a/reelforge/i18n/locales/en_US.json b/reelforge/i18n/locales/en_US.json index 91e7c4c..9a55dbb 100644 --- a/reelforge/i18n/locales/en_US.json +++ b/reelforge/i18n/locales/en_US.json @@ -76,6 +76,20 @@ "template.modern": "Modern", "template.neon": "Neon", "template.custom_help": "💡 Custom: Place .html files in templates/ folder", + "template.preview_title": "🔍 Preview Template", + "template.preview_param_title": "Title", + "template.preview_param_text": "Text", + "template.preview_param_image": "Image Path", + "template.preview_param_width": "Width", + "template.preview_param_height": "Height", + "template.preview_default_title": "AI Changes Content Creation", + "template.preview_default_text": "Artificial intelligence is transforming the way we create content, making it easy for everyone to produce professional-grade videos.", + "template.preview_button": "🖼️ Generate Preview", + "template.preview_generating": "Generating template preview...", + "template.preview_success": "✅ Preview generated successfully!", + "template.preview_failed": "❌ Preview failed: {error}", + "template.preview_image_help": "Supports local path or URL", + "template.preview_caption": "Template Preview: {template}", "video.title": "🎬 Video Settings", "video.frames": "Scenes", diff --git a/reelforge/i18n/locales/zh_CN.json b/reelforge/i18n/locales/zh_CN.json index c0c3da0..189a540 100644 --- a/reelforge/i18n/locales/zh_CN.json +++ b/reelforge/i18n/locales/zh_CN.json @@ -76,6 +76,20 @@ "template.modern": "现代", "template.neon": "霓虹", "template.custom_help": "💡 自定义:将 .html 文件放入 templates/ 文件夹", + "template.preview_title": "🔍 预览模板", + "template.preview_param_title": "标题", + "template.preview_param_text": "文本", + "template.preview_param_image": "图片路径", + "template.preview_param_width": "宽度", + "template.preview_param_height": "高度", + "template.preview_default_title": "AI 改变内容创作", + "template.preview_default_text": "人工智能正在改变内容创作的方式,让每个人都能轻松制作专业级视频。", + "template.preview_button": "🖼️ 生成预览", + "template.preview_generating": "正在生成模板预览...", + "template.preview_success": "✅ 预览生成成功!", + "template.preview_failed": "❌ 预览失败:{error}", + "template.preview_image_help": "支持本地路径或 URL", + "template.preview_caption": "模板预览:{template}", "video.title": "🎬 视频设置", "video.frames": "分镜数", diff --git a/reelforge/services/frame_html.py b/reelforge/services/frame_html.py index d9183d4..92980ec 100644 --- a/reelforge/services/frame_html.py +++ b/reelforge/services/frame_html.py @@ -206,7 +206,7 @@ class HTMLFrameGenerator: Args: title: Video title text: Narration text for this frame - image: Path to AI-generated image + image: Path to AI-generated image (supports relative path, absolute path, or HTTP URL) ext: Additional data (content_title, content_author, etc.) width: Frame width in pixels height: Frame height in pixels @@ -214,6 +214,22 @@ class HTMLFrameGenerator: Returns: Path to generated frame image """ + # Convert image path to absolute path or file:// URL for html2image + if image and not image.startswith(('http://', 'https://', 'data:', 'file://')): + # Local file path - convert to absolute path and file:// URL + image_path = Path(image) + if not image_path.is_absolute(): + # Relative to current working directory (project root) + image_path = Path.cwd() / image + + # Ensure the file exists + if not image_path.exists(): + logger.warning(f"Image file not found: {image_path}") + else: + # Convert to file:// URL for html2image compatibility + image = image_path.as_uri() + logger.debug(f"Converted image path to: {image}") + # Build variable context context = { # Required variables diff --git a/resources/example.png b/resources/example.png new file mode 100644 index 0000000..7220a4b Binary files /dev/null and b/resources/example.png differ diff --git a/web/app.py b/web/app.py index 4c41694..8160dee 100644 --- a/web/app.py +++ b/web/app.py @@ -610,6 +610,93 @@ def main(): index=default_template_index, label_visibility="collapsed" ) + + # Template preview expander + with st.expander(tr("template.preview_title"), expanded=False): + col1, col2 = st.columns(2) + + with col1: + preview_title = st.text_input( + tr("template.preview_param_title"), + value=tr("template.preview_default_title"), + key="preview_title" + ) + preview_image = st.text_input( + tr("template.preview_param_image"), + value="resources/example.png", + help=tr("template.preview_image_help"), + key="preview_image" + ) + + with col2: + preview_text = st.text_area( + tr("template.preview_param_text"), + value=tr("template.preview_default_text"), + height=100, + key="preview_text" + ) + + # Size settings in a compact row + col3, col4 = st.columns(2) + with col3: + preview_width = st.number_input( + tr("template.preview_param_width"), + value=1080, + min_value=100, + max_value=4096, + step=10, + key="preview_width" + ) + with col4: + preview_height = st.number_input( + tr("template.preview_param_height"), + value=1920, + min_value=100, + max_value=4096, + step=10, + key="preview_height" + ) + + # Preview button + if st.button(tr("template.preview_button"), key="btn_preview_template", use_container_width=True): + with st.spinner(tr("template.preview_generating")): + try: + from reelforge.services.frame_html import HTMLFrameGenerator + + # Use the currently selected template + template_path = f"templates/{frame_template}" + generator = HTMLFrameGenerator(template_path) + + # Generate preview + preview_path = run_async(generator.generate_frame( + title=preview_title, + text=preview_text, + image=preview_image, + width=preview_width, + height=preview_height + )) + + # Display preview + if preview_path: + st.success(tr("template.preview_success")) + + # Calculate display width (max 500px or 1/3 of original) + display_width = min(500, preview_width // 3) + + st.image( + preview_path, + caption=tr("template.preview_caption", template=frame_template), + # width=display_width + ) + + # Show file path + st.caption(f"📁 {preview_path}") + else: + st.error("Failed to generate preview") + + except Exception as e: + st.error(tr("template.preview_failed", error=str(e))) + logger.exception(e) # ======================================================================== # Right Column: Generate Button + Progress + Video Preview