更新图片插入位置:

有标题时选择标题前后插入
无标题是可自定义段落插入
This commit is contained in:
wsb1224 2025-10-15 17:10:50 +08:00
parent 7ebf20ed6c
commit 6b5e4adea6
4 changed files with 70 additions and 11 deletions

View File

@ -41,6 +41,8 @@ class Config:
self.image_width = 6 # 英寸
self.image_alignment = "center" # left, center, right
self.image_strategy = "cycle" # cycle, truncate, repeat_last
self.image_insert_position = "after_title" # before_title, after_title (有标题时)
self.image_insert_interval = 5 # 无标题时每隔几段插入一张图片
# 文档格式配置
self.line_spacing = 1.5
@ -95,6 +97,9 @@ class Config:
self.image_width = section.getfloat('image_width', self.image_width)
self.image_alignment = section.get('image_alignment', self.image_alignment)
self.image_strategy = section.get('image_strategy', self.image_strategy)
# 新增的图片插入配置
self.image_insert_position = section.get('image_insert_position', self.image_insert_position)
self.image_insert_interval = section.getint('image_insert_interval', self.image_insert_interval)
# 加载文档格式配置
if 'DocumentFormat' in config_parser:
@ -149,7 +154,9 @@ class Config:
'image_resize': self.image_resize,
'image_width': str(self.image_width),
'image_alignment': self.image_alignment,
'image_strategy': self.image_strategy
'image_strategy': self.image_strategy,
'image_insert_position': self.image_insert_position,
'image_insert_interval': str(self.image_insert_interval)
}
# 保存文档格式配置
@ -201,7 +208,9 @@ class Config:
'image_resize': self.image_resize,
'image_width': self.image_width,
'image_alignment': self.image_alignment,
'image_strategy': self.image_strategy
'image_strategy': self.image_strategy,
'image_insert_position': self.image_insert_position,
'image_insert_interval': self.image_insert_interval
},
'document_format': {
'line_spacing': self.line_spacing,
@ -246,6 +255,8 @@ class Config:
self.image_width = ip.get('image_width', self.image_width)
self.image_alignment = ip.get('image_alignment', self.image_alignment)
self.image_strategy = ip.get('image_strategy', self.image_strategy)
self.image_insert_position = ip.get('image_insert_position', self.image_insert_position)
self.image_insert_interval = ip.get('image_insert_interval', self.image_insert_interval)
# 文档格式配置
if 'document_format' in config_dict:

BIN
dist/txt2md2docx.exe vendored

Binary file not shown.

View File

@ -31,6 +31,7 @@ class DocxGenerator:
"""初始化DOCX生成器"""
self.temp_files = [] # 跟踪临时文件以便清理
self.current_document_style = None # 当前使用的文档样式
self.paragraph_count = 0 # 段落计数器,用于无标题文章的图片插入控制
def generate(self, sections: List[Dict[str, Any]], image_files: List[str],
output_path: str, progress_callback: Optional[Callable] = None) -> bool:
@ -167,6 +168,12 @@ class DocxGenerator:
run.font.bold = True
self._apply_inline_formatting(para, heading_text)
# 如果有标题,根据配置决定在标题前还是后插入图片
if image_count > 0 and image_index < image_count:
# 检查是否需要在标题前插入图片
if hasattr(config, 'image_insert_position') and config.image_insert_position == "before_title":
image_index = self._insert_section_image(doc, image_files, image_index, image_count, output_path)
elif section['content'] != '前置内容':
heading_text = text_processor.process_text_content(section['content'])
para = doc.add_paragraph()
@ -194,17 +201,28 @@ class DocxGenerator:
if not elements:
return image_index
# 处理第一个非空元素后插入图片
first_content_added = False
# 处理元素
for element in elements:
# 添加元素到文档
self._add_element_to_doc(doc, element)
# 在第一个内容元素后插入图片
if not first_content_added and element['type'] not in ['empty']:
first_content_added = True
image_index = self._insert_section_image(doc, image_files, image_index, image_count, output_path)
# 根据文章结构决定图片插入策略
if element['type'] not in ['empty']:
# 如果有标题,根据配置决定在标题后插入图片
if section['level'] > 0 and section['level'] <= config.title_levels:
# 有标题的文章,在标题后的第一个内容后插入图片
if hasattr(config, 'image_insert_position') and config.image_insert_position == "after_title":
image_index = self._insert_section_image(doc, image_files, image_index, image_count, output_path)
# 插入一次后就不再插入,直到下一个标题
break
else:
# 无标题的文章,根据段落计数控制图片插入间隔
self.paragraph_count += 1
if image_count > 0 and image_index < image_count:
# 检查是否需要插入图片(根据配置的间隔)
image_insert_interval = getattr(config, 'image_insert_interval', 5) # 默认每5段插入一张图片
if self.paragraph_count % image_insert_interval == 0:
image_index = self._insert_section_image(doc, image_files, image_index, image_count, output_path)
return image_index
@ -574,7 +592,8 @@ class DocxGenerator:
"""
try:
# 使用优化方法处理图片
temp_dir = os.path.dirname(output_path)
temp_dir = os.path.join(os.path.dirname(output_path), "temp_images")
os.makedirs(temp_dir, exist_ok=True)
optimized_image_path = ImageProcessor.optimize_image_for_docx(image_path, temp_dir)
# 处理图片(方向修正和尺寸调整)
@ -583,7 +602,6 @@ class DocxGenerator:
temp_img_path = None
if config.image_resize == "width":
# 需要保存临时图片
os.makedirs(temp_dir, exist_ok=True)
temp_img_path = os.path.join(temp_dir, f"temp_img_{hash(image_path)}.png")
img.save(temp_img_path)
self.temp_files.append(temp_img_path)

View File

@ -228,6 +228,28 @@ def _create_image_tab(parent):
ttk.Separator(parent, orient='horizontal').pack(fill='x', padx=10, pady=15)
# 图片插入策略(新增)
ttk.Label(parent, text='图片插入策略:', font=('', 10, 'bold')).pack(anchor='w', padx=10, pady=(0, 5))
# 有标题时的图片插入位置
ttk.Label(parent, text='有标题时:', font=('', 9)).pack(anchor='w', padx=20, pady=(0, 2))
position_var = tk.StringVar(value=getattr(config, 'image_insert_position', 'after_title'))
ttk.Radiobutton(parent, text='标题前插入', variable=position_var, value='before_title').pack(anchor='w', padx=30, pady=1)
ttk.Radiobutton(parent, text='标题后插入', variable=position_var, value='after_title').pack(anchor='w', padx=30, pady=1)
position_var.trace('w', lambda *args: setattr(config, 'image_insert_position', position_var.get()))
# 无标题时的图片插入间隔
interval_frame = ttk.Frame(parent)
interval_frame.pack(anchor='w', padx=20, pady=5)
ttk.Label(interval_frame, text='无标题时每隔', font=('', 9)).pack(side='left')
interval_var = tk.StringVar(value=str(getattr(config, 'image_insert_interval', 5)))
interval_entry = ttk.Entry(interval_frame, textvariable=interval_var, width=5)
interval_entry.pack(side='left', padx=2)
ttk.Label(interval_frame, text='段插入一张图片', font=('', 9)).pack(side='left')
interval_var.trace('w', lambda *args: _update_image_interval(interval_var.get()))
ttk.Separator(parent, orient='horizontal').pack(fill='x', padx=10, pady=15)
# 图片不足时策略
ttk.Label(parent, text='图片不足时策略:', font=('', 10, 'bold')).pack(anchor='w', padx=10, pady=(0, 5))
@ -246,6 +268,14 @@ def _update_image_width(value):
pass
def _update_image_interval(value):
"""更新图片插入间隔"""
try:
config.image_insert_interval = int(value)
except:
pass
def _reset_to_default(char_vars):
"""重置为默认值"""
from config import Config