【剪映小助手源码精讲】第28章 文本样式服务

第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 性能优化

文本样式服务采用了多种性能优化策略:

  1. 高效匹配算法:使用优化的字符串匹配算法
  2. 缓存机制:缓存常用的样式模板和颜色转换结果
  3. 批量处理:支持批量处理多个文本样式请求
  4. 内存优化:使用生成器处理大文本,避免内存溢出

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
相关推荐
皇族崛起2 小时前
【3D标注】- Unreal Engine 5.7 与 Python 交互基础
python·3d·ue5
你想知道什么?2 小时前
Python基础篇(上) 学习笔记
笔记·python·学习
阿杰学AI3 小时前
AI核心知识44——大语言模型之Reward Hacking(简洁且通俗易懂版)
人工智能·ai·语言模型·aigc·ai安全·奖励欺骗·reward hacking
Swizard3 小时前
速度与激情:Android Python + CameraX 零拷贝实时推理指南
android·python·ai·移动开发
一直跑3 小时前
Liunx服务器centos7离线升级内核(Liunx服务器centos7.9离线/升级系统内核)
python
leocoder3 小时前
大模型基础概念入门 + 代码实战(实现一个多轮会话机器人)
前端·人工智能·python
Buxxxxxx3 小时前
DAY 37 深入理解SHAP图
python
ada7_3 小时前
LeetCode(python)108.将有序数组转换为二叉搜索树
数据结构·python·算法·leetcode
请一直在路上3 小时前
python文件打包成exe(虚拟环境打包,减少体积)
开发语言·python
浩瀚地学3 小时前
【Arcpy】入门学习笔记(五)-矢量数据
经验分享·笔记·python·arcgis·arcpy