You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

基于ezdxf的Python文本尺寸与精确定位实现求助

解决方案:DXF文本精准适配指定区域与位置

核心思路

要让不同文本固定填充到同一X/Y区域,关键是先获取文本原始边界,再通过缩放+平移的矩阵变换,将文本精准映射到目标区域。以下提供两种可行方案,分别适用于保留可编辑文本对象和仅需视觉效果的场景。


方案1:保留可编辑Text对象(推荐)

通过ezdxf的边界盒计算+矩阵变换,将文本缩放后精准定位到目标区域,同时保留文本的可编辑属性。

代码示例

import ezdxf
from ezdxf.math import Matrix44, BoundingBox

def fit_text_to_box(msp, text_content, target_min_x, target_min_y, target_max_x, target_max_y, font="Arial"):
    # 1. 创建临时文本,以左下角为对齐基准,初始高度设为1方便比例计算
    temp_text = msp.add_text(
        text_content,
        dxfattribs={
            "height": 1,
            "justify": 1,  # LEFT_BOTTOM对齐,插入点为文本左下角
            "font": font
        }
    )
    temp_text.set_pos((0, 0))
    
    # 2. 获取文本原始边界盒
    bbox = temp_text.get_bounding_box()
    if not bbox:
        temp_text.delete()
        return None
    
    # 3. 计算缩放比例:匹配目标区域的宽高
    target_width = target_max_x - target_min_x
    target_height = target_max_y - target_min_y
    scale_x = target_width / bbox.width
    scale_y = target_height / bbox.height
    
    # 4. 构建变换矩阵:先缩放,再平移到目标区域左下角
    scale_matrix = Matrix44.scale(sx=scale_x, sy=scale_y, sz=1)
    # 修正平移偏移:抵消原始边界的偏移量
    translate_matrix = Matrix44.translate(
        x=target_min_x - (bbox.extmin.x * scale_x),
        y=target_min_y - (bbox.extmin.y * scale_y),
        z=0
    )
    transform = translate_matrix @ scale_matrix
    
    # 5. 应用变换
    temp_text.transform(transform)
    return temp_text

# 测试使用
if __name__ == "__main__":
    doc = ezdxf.new(dxfversion="R2010")
    msp = doc.modelspace()
    
    # 定义固定目标区域:宽10,高5
    TARGET_AREA = (0, 0, 10, 5)
    # 分别添加不同长度的文本,都适配到同一区域(第二个区域偏移12单位方便对比)
    fit_text_to_box(msp, "base", *TARGET_AREA)
    fit_text_to_box(msp, "welding point", 12, 0, 22, 5)
    
    doc.saveas("fit_text_editable.dxf")

方案2:转为路径实现精准适配(无编辑属性)

如果不需要保留文本的可编辑性,可将文本转为多段线路径,通过路径的边界盒计算和变换实现更精准的适配,适合特殊字体或复杂字符场景。

代码示例

import ezdxf
from ezdxf.math import Matrix44, BoundingBox
from ezdxf.addons import text2path

def fit_text_path_to_box(msp, text_content, target_min_x, target_min_y, target_max_x, target_max_y, font="Arial"):
    # 1. 将文本转为路径
    paths = text2path.make_paths_from_str(text_content, font=font, height=1)
    if not paths:
        return None
    
    # 2. 计算路径的整体边界盒
    bbox = BoundingBox()
    for path in paths:
        bbox.extend(path.flattening())
    
    # 3. 计算缩放比例
    target_width = target_max_x - target_min_x
    target_height = target_max_y - target_min_y
    scale_x = target_width / bbox.width
    scale_y = target_height / bbox.height
    
    # 4. 变换路径
    transform = Matrix44.scale(scale_x, scale_y, 1) @ Matrix44.translate(
        target_min_x - bbox.extmin.x * scale_x,
        target_min_y - bbox.extmin.y * scale_y,
        0
    )
    
    # 5. 将变换后的路径添加到模型空间
    for path in paths:
        path.transform(transform)
        msp.add_lwpolyline(path.flattening(), dxfattribs={"closed": False})
    return paths

# 测试使用
if __name__ == "__main__":
    doc = ezdxf.new(dxfversion="R2010")
    msp = doc.modelspace()
    
    fit_text_path_to_box(msp, "base", 0, 0, 10, 5)
    fit_text_path_to_box(msp, "welding point", 12, 0, 22, 5)
    
    doc.saveas("fit_text_path.dxf")

关键注意事项

  • 字体一致性:必须确保使用的字体在DXF查看器/编辑器中可用,否则边界盒计算会出现偏差,建议使用系统内置的TrueType字体(如Arial)。
  • 对齐基准:方案1中必须设置justify=1(左下角对齐),否则平移计算会出错;若需其他对齐方式,需调整边界盒基准点的计算逻辑。
  • 边界盒准确性:部分特殊字体或字符可能无法通过get_bounding_box()获取准确边界,此时建议使用方案2的路径转换方式。

内容的提问来源于stack exchange,提问作者Natan Salazar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.27 03:52:50