第28章 文本样式服务
28.1 概述
文本样式服务是剪映小助手的重要功能模块,主要负责处理文本内容的富文本样式设置。该服务支持关键词高亮、自定义字体大小、颜色设置等功能,可以为视频字幕、标题等文本元素创建丰富的视觉效果。服务支持多关键词匹配,避免重叠,并提供灵活的样式配置选项。
28.2 核心实现
28.2.1 服务入口函数
文本样式服务的核心实现位于 src/service/add_text_style.py 文件中:
python
async def add_text_style(request: AddTextStyleRequest) -> AddTextStyleResponse:
"""添加文本样式"""
logger.info(f"处理文本样式,文本长度: {len(request.text)}")
# 参数验证
if not request.text:
raise ValueError("文本内容不能为空")
if not request.keyword:
raise ValueError("关键词不能为空")
# 处理关键词
keywords = process_keywords(request.keyword)
if not keywords:
raise ValueError("关键词处理失败")
# 查找关键词位置
keyword_positions = find_keyword_positions(request.text, keywords)
# 生成文本样式
text_style = generate_text_style(
request.text,
keyword_positions,
request
)
return AddTextStyleResponse(
text_style=json.dumps(text_style, ensure_ascii=False)
)
28.2.2 关键词处理
关键词处理支持多关键词,使用竖线分隔:
python
def process_keywords(keyword: str) -> List[str]:
"""处理关键词,支持多关键词用|分隔"""
if not keyword:
return []
# 按|分割关键词
keywords = [k.strip() for k in keyword.split('|') if k.strip()]
# 去重并排序(按长度降序,避免短词被长词包含)
keywords = list(set(keywords))
keywords.sort(key=len, reverse=True)
logger.info(f"处理后的关键词: {keywords}")
return keywords
28.2.3 关键词位置查找
查找关键词在文本中的位置,避免重叠匹配:
python
def find_keyword_positions(text: str, keywords: List[str]) -> List[dict]:
"""查找关键词位置,避免重叠"""
positions = []
text_lower = text.lower()
for keyword in keywords:
if not keyword:
continue
keyword_lower = keyword.lower()
start = 0
while True:
# 查找关键词位置
pos = text_lower.find(keyword_lower, start)
if pos == -1:
break
# 检查是否与已有位置重叠
overlap = False
for existing_pos in positions:
if (pos < existing_pos['end'] and
pos + len(keyword) > existing_pos['start']):
overlap = True
break
if not overlap:
positions.append({
'keyword': keyword,
'start': pos,
'end': pos + len(keyword),
'text': text[pos:pos + len(keyword)]
})
start = pos + 1
# 按起始位置排序
positions.sort(key=lambda x: x['start'])
logger.info(f"找到 {len(positions)} 个关键词位置")
return positions
28.2.4 文本样式生成
根据关键词位置生成富文本样式:
python
def generate_text_style(text: str, positions: List[dict], request: AddTextStyleRequest) -> dict:
"""生成文本样式"""
text_style = {
'text': text,
'styles': []
}
last_end = 0
# 处理每个关键词位置
for pos in positions:
# 添加普通文本部分
if pos['start'] > last_end:
normal_text = text[last_end:pos['start']]
if normal_text:
text_style['styles'].append({
'text': normal_text,
'font_size': request.font_size,
'color': '#000000', # 普通文本默认黑色
'bold': False,
'italic': False
})
# 添加关键词样式
keyword_text = pos['text']
keyword_color = hex_to_rgb(request.keyword_color)
text_style['styles'].append({
'text': keyword_text,
'font_size': request.keyword_font_size,
'color': request.keyword_color,
'color_rgb': keyword_color,
'bold': True, # 关键词默认加粗
'italic': False
})
last_end = pos['end']
# 处理剩余文本
if last_end < len(text):
remaining_text = text[last_end:]
if remaining_text:
text_style['styles'].append({
'text': remaining_text,
'font_size': request.font_size,
'color': '#000000',
'bold': False,
'italic': False
})
return text_style
28.2.5 颜色转换函数
将十六进制颜色转换为RGB值:
python
def hex_to_rgb(hex_color: str) -> tuple:
"""十六进制颜色转RGB"""
try:
# 移除#号
hex_color = hex_color.lstrip('#')
# 转换为RGB
if len(hex_color) == 3:
# 简写格式 #RGB
r = int(hex_color[0] * 2, 16)
g = int(hex_color[1] * 2, 16)
b = int(hex_color[2] * 2, 16)
elif len(hex_color) == 6:
# 完整格式 #RRGGBB
r = int(hex_color[0:2], 16)
g = int(hex_color[2:4], 16)
b = int(hex_color[4:6], 16)
else:
raise ValueError(f"无效的颜色格式: {hex_color}")
return (r, g, b)
except Exception as e:
logger.error(f"颜色转换失败: {str(e)}")
return (0, 0, 0) # 默认黑色
28.3 样式属性定义与应用
28.3.1 文本样式属性
系统支持以下文本样式属性:
python
class TextStyle:
# 基本属性
TEXT = "text" # 文本内容
FONT_SIZE = "font_size" # 字体大小
COLOR = "color" # 颜色(十六进制)
COLOR_RGB = "color_rgb" # 颜色(RGB)
# 样式属性
BOLD = "bold" # 加粗
ITALIC = "italic" # 斜体
UNDERLINE = "underline" # 下划线
STRIKETHROUGH = "strikethrough" # 删除线
# 高级属性
FONT_FAMILY = "font_family" # 字体族
LETTER_SPACING = "letter_spacing" # 字间距
LINE_HEIGHT = "line_height" # 行高
OPACITY = "opacity" # 透明度
28.3.2 关键词样式配置
关键词样式支持丰富的配置选项:
python
# 关键词默认样式
keyword_default_style = {
'font_size': 15, # 关键词字体大小
'color': '#ff7100', # 关键词颜色(橙色)
'bold': True, # 加粗
'italic': False, # 不斜体
'underline': False, # 无下划线
'background_color': None, # 无背景色
'border_color': None, # 无边框色
'border_width': 0 # 无边框
}
28.3.3 普通文本样式配置
普通文本的默认样式配置:
python
# 普通文本默认样式
normal_default_style = {
'font_size': 12, # 普通文本字体大小
'color': '#000000', # 黑色
'bold': False, # 不加粗
'italic': False, # 不斜体
'underline': False, # 无下划线
'background_color': None, # 无背景色
'opacity': 1.0 # 不透明
}
28.4 数据结构定义
28.4.1 请求参数模型
文本样式服务的请求参数定义在 src/schemas/add_text_style.py 中:
python
class AddTextStyleRequest(BaseModel):
"""创建文本富文本样式请求参数"""
text: str = Field(..., description="要处理的文本内容")
keyword: str = Field(..., description="关键词,多个用 | 分隔")
font_size: int = Field(default=12, description="普通文本的字体大小")
keyword_color: str = Field(default="#ff7100", description="关键词文本颜色(十六进制)")
keyword_font_size: int = Field(default=15, description="关键词字体大小")
28.4.2 响应参数模型
python
class AddTextStyleResponse(BaseModel):
"""创建文本富文本样式响应参数"""
text_style: str = Field(default="", description="文本样式JSON字符串")
28.5 高级功能
28.5.1 多关键词匹配策略
系统支持多种关键词匹配策略:
python
class KeywordMatchStrategy:
EXACT = "exact" # 精确匹配
CONTAINS = "contains" # 包含匹配
PREFIX = "prefix" # 前缀匹配
SUFFIX = "suffix" # 后缀匹配
REGEX = "regex" # 正则匹配
28.5.2 重叠处理策略
当多个关键词重叠时的处理策略:
python
class OverlapStrategy:
FIRST_MATCH = "first_match" # 优先匹配第一个
LONGEST_MATCH = "longest_match" # 优先匹配最长的
SHORTEST_MATCH = "shortest_match" # 优先匹配最短的
ALL_MATCH = "all_match" # 匹配所有(不处理重叠)
28.5.3 样式模板系统
预定义的样式模板:
python
# 样式模板
text_style_templates = {
'title': { # 标题样式
'font_size': 24,
'color': '#333333',
'bold': True,
'font_family': 'Arial'
},
'subtitle': { # 副标题样式
'font_size': 18,
'color': '#666666',
'bold': False,
'font_family': 'Arial'
},
'highlight': { # 高亮样式
'font_size': 14,
'color': '#ff6600',
'bold': True,
'background_color': '#fff3cd'
},
'code': { # 代码样式
'font_size': 12,
'color': '#e83e8c',
'font_family': 'Monaco',
'background_color': '#f8f9fa'
}
}
28.6 异常处理
文本样式服务定义了完善的异常处理机制:
python
# 无效的文本内容
INVALID_TEXT_CONTENT = HTTPException(
status_code=400,
detail="无效的文本内容"
)
# 无效的关键词
INVALID_KEYWORD = HTTPException(
status_code=400,
detail="无效的关键词"
)
# 文本样式生成失败
TEXT_STYLE_GENERATION_FAILED = HTTPException(
status_code=500,
detail="文本样式生成失败"
)
# 无效的颜色格式
INVALID_COLOR_FORMAT = HTTPException(
status_code=400,
detail="无效的颜色格式"
)
28.7 API接口定义
python
@router.post("/addTextStyle", response_model=AddTextStyleResponse)
async def add_text_style_endpoint(request: AddTextStyleRequest):
"""添加文本样式"""
try:
return await add_text_style(request)
except Exception as e:
logger.error(f"添加文本样式失败: {str(e)}")
raise TEXT_STYLE_GENERATION_FAILED
28.8 使用示例
28.8.1 请求示例
json
{
"text": "欢迎使用剪映小助手,这是一个强大的视频编辑工具",
"keyword": "剪映|视频编辑|工具",
"font_size": 14,
"keyword_color": "#ff6600",
"keyword_font_size": 16
}
28.8.2 响应示例
json
{
"text_style": "{\"text\":\"欢迎使用剪映小助手,这是一个强大的视频编辑工具\",\"styles\":[{\"text\":\"欢迎使用\",\"font_size\":14,\"color\":\"#000000\",\"bold\":false,\"italic\":false},{\"text\":\"剪映\",\"font_size\":16,\"color\":\"#ff6600\",\"color_rgb\":[255,102,0],\"bold\":true,\"italic\":false},{\"text\":\"小助手,这是一个强大的\",\"font_size\":14,\"color\":\"#000000\",\"bold\":false,\"italic\":false},{\"text\":\"视频编辑\",\"font_size\":16,\"color\":\"#ff6600\",\"color_rgb\":[255,102,0],\"bold\":true,\"italic\":false},{\"text\":\"工具\",\"font_size\":16,\"color\":\"#ff6600\",\"color_rgb\":[255,102,0],\"bold\":true,\"italic\":false}]}"
}
28.9 性能优化
文本样式服务采用了多种性能优化策略:
- 高效匹配算法:使用优化的字符串匹配算法
- 缓存机制:缓存常用的样式模板和颜色转换结果
- 批量处理:支持批量处理多个文本样式请求
- 内存优化:使用生成器处理大文本,避免内存溢出
28.10 扩展性设计
文本样式服务具有良好的扩展性:
- 样式属性扩展:易于添加新的样式属性
- 匹配策略扩展:支持自定义关键词匹配策略
- 模板系统扩展:支持动态添加样式模板
- 输出格式扩展:支持多种输出格式(JSON、XML、HTML等)
附录
代码仓库地址:
- GitHub:
https://github.com/Hommy-master/capcut-mate - Gitee:
https://gitee.com/taohongmin-gitee/capcut-mate
接口文档地址:
- API文档地址:
https://docs.jcaigc.cn