| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192 |
- """
- 保存功能控件
- """
- import streamlit as st
- import io
- import json
- from pathlib import Path
- from typing import Dict
- from .drawing import draw_clean_table_lines
- def create_save_section(work_mode: str, structure: Dict, image, line_width: int, output_config: Dict):
- """
- 保存设置(目录/命名来自配置)
-
- Args:
- work_mode: 工作模式
- structure: 表格结构
- image: 图片对象
- line_width: 线条宽度
- output_config: 输出配置(兜底用)
- """
- st.divider()
- # 🔑 优先使用当前数据源的输出配置
- if 'current_output_config' in st.session_state:
- active_output_config = st.session_state.current_output_config
- st.info(f"📂 保存位置:{active_output_config.get('directory', 'N/A')}")
- else:
- active_output_config = output_config
- defaults = active_output_config.get("defaults", {})
- line_colors = active_output_config.get("line_colors") or [
- {"name": "黑色", "rgb": [0, 0, 0]},
- {"name": "蓝色", "rgb": [0, 0, 255]},
- {"name": "红色", "rgb": [255, 0, 0]},
- ]
- save_col1, save_col2, save_col3 = st.columns(3)
- with save_col1:
- save_structure = st.checkbox(
- "保存表格结构配置",
- value=bool(defaults.get("save_structure", True)),
- )
- with save_col2:
- save_image = st.checkbox(
- "保存表格线图片",
- value=bool(defaults.get("save_image", True)),
- )
- color_names = [c["name"] for c in line_colors]
- default_color = defaults.get("line_color", color_names[0])
- default_index = (
- color_names.index(default_color)
- if default_color in color_names
- else 0
- )
- with save_col3:
- line_color_option = st.selectbox(
- "线条颜色",
- color_names,
- index=default_index,
- label_visibility="collapsed",
- key="save_line_color"
- )
- if st.button("💾 保存", type="primary"):
- output_dir = Path(active_output_config.get("directory", "output/table_structures"))
- output_dir.mkdir(parents=True, exist_ok=True)
- structure_suffix = active_output_config.get("structure_suffix", "_structure.json")
- image_suffix = active_output_config.get("image_suffix", "_with_lines.png")
- # 确定文件名
- base_name = _determine_base_name(work_mode)
-
- saved_files = []
-
- if save_structure:
- _save_structure_file(
- structure,
- output_dir,
- base_name,
- structure_suffix,
- saved_files
- )
-
- if save_image:
- _save_image_file(
- image,
- structure,
- line_width,
- line_color_option,
- line_colors,
- output_dir,
- base_name,
- image_suffix,
- saved_files
- )
-
- if saved_files:
- st.success(f"✅ 已保存 {len(saved_files)} 个文件:")
- for file_type, file_path in saved_files:
- st.info(f" • {file_type}: {file_path}")
-
- # 显示当前数据源信息
- if 'current_data_source' in st.session_state:
- ds = st.session_state.current_data_source
- with st.expander("📋 数据源信息"):
- st.json({
- "名称": ds.get("name"),
- "JSON目录": str(ds.get("json_dir")),
- "图片目录": str(ds.get("image_dir")),
- "输出目录": str(output_dir),
- })
- def _determine_base_name(work_mode: str) -> str:
- """确定保存文件的基础名称"""
- if work_mode == "🆕 新建标注" or work_mode == "new":
- if st.session_state.loaded_json_name:
- return Path(st.session_state.loaded_json_name).stem
- else:
- return "table_structure"
- else:
- if st.session_state.loaded_config_name:
- base_name = Path(st.session_state.loaded_config_name).stem
- if base_name.endswith('_structure'):
- base_name = base_name[:-10]
- return base_name
- elif st.session_state.loaded_image_name:
- return Path(st.session_state.loaded_image_name).stem
- else:
- return "table_structure"
- def _save_structure_file(structure, output_dir, base_name, suffix, saved_files):
- """保存结构配置文件"""
- structure_filename = f"{base_name}{suffix}"
- structure_path = output_dir / structure_filename
- # save_structure_to_config(structure, structure_path)
- with open(structure_path, 'w', encoding='utf-8') as f:
- json.dump(structure, f, indent=2, ensure_ascii=False)
- saved_files.append(("配置文件", structure_path))
-
- with open(structure_path, 'r') as f:
- st.download_button(
- "📥 下载配置文件",
- f.read(),
- file_name=f"{base_name}_structure.json",
- mime="application/json"
- )
- def _save_image_file(image, structure, line_width, color_option, line_colors,
- output_dir, base_name, suffix, saved_files):
- """保存表格线图片"""
- if image is None:
- st.warning("⚠️ 无法保存图片:未加载图片文件")
- return
-
- selected_color_rgb = next(
- (tuple(c["rgb"]) for c in line_colors if c["name"] == color_option),
- (0, 0, 0),
- )
-
- clean_img = draw_clean_table_lines(
- image,
- structure,
- line_width=line_width,
- line_color=selected_color_rgb,
- )
-
- image_filename = f"{base_name}{suffix}"
- output_image_path = output_dir / image_filename
- clean_img.save(output_image_path)
- saved_files.append(("表格线图片", output_image_path))
-
- buf = io.BytesIO()
- clean_img.save(buf, format='PNG')
- buf.seek(0)
-
- st.download_button(
- "📥 下载表格线图片",
- buf,
- file_name=f"{base_name}_with_lines.png",
- mime="image/png"
- )
|