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

Python调用Inkscape Shell模式,如何获取query-all命令的输出?

解决Inkscape Shell模式下捕获query-all输出的问题

核心问题分析

你当前无法捕获query-all输出的主要原因是启用了shell=True,额外启动的Shell层会干扰Inkscape原生输出的捕获。同时,Inkscape Shell模式会以>作为命令提示符,需要通过识别提示符来分离命令输出与系统提示。

解决方案与修改后的代码

import subprocess
import tempfile
import os
import threading

# 后台线程处理stderr,防止缓冲区满导致进程阻塞
def handle_stderr(process):
    for line in iter(process.stderr.readline, ''):
        # 可根据需求改为日志记录或其他处理
        print(f"Inkscape错误输出: {line.strip()}")

INKSCAPE_EXE_PATH = "你的Inkscape可执行文件路径"
LIST_OF_SVGs = []  # 替换为你的SVG内容列表

# 启动Inkscape Shell模式,移除shell=True避免额外Shell层
process = subprocess.Popen(
    [INKSCAPE_EXE_PATH, "--shell"],
    stdin=subprocess.PIPE,
    stdout=subprocess.PIPE,
    stderr=subprocess.PIPE,
    text=True,
    bufsize=1  # 行缓冲,便于逐行读取输出
)

# 启动stderr处理线程
stderr_thread = threading.Thread(target=handle_stderr, args=(process,))
stderr_thread.daemon = True
stderr_thread.start()

# 读取Inkscape启动后的初始提示符>
process.stdout.readline()

def create_image_data(SVGs):
    page = 0  # 自定义页码计数,按需调整
    for svg in SVGs:
        filename = f"svg_output"  # 自定义基础文件名
        # 创建临时SVG文件,退出with块自动删除
        with tempfile.NamedTemporaryFile(delete=True, suffix='.svg', mode='wb') as temp_svg:
            temp_svg.write(svg.encode('utf-8'))
            temp_svg.flush()
            temp_svg_path = temp_svg.name

            # 打开SVG文件并确认执行完成
            process.stdin.write(f"file-open:{temp_svg_path}\n")
            process.stdin.flush()
            process.stdout.readline()  # 读取执行后的提示符>

            # 设置导出路径并确认
            export_path = os.path.join(os.getcwd(), f'{filename}-{page}.png')
            process.stdin.write(f"export-filename:{export_path}\n")
            process.stdin.flush()
            process.stdout.readline()

            # 执行导出并确认
            process.stdin.write("export-do\n")
            process.stdin.flush()
            process.stdout.readline()

            # 执行query-all并捕获输出
            process.stdin.write("query-all\n")
            process.stdin.flush()
            
            # 读取输出直到遇到提示符>,提取有效数据
            bbox_lines = []
            while True:
                line = process.stdout.readline()
                if not line:
                    break
                stripped_line = line.strip()
                if stripped_line == ">":
                    break
                if stripped_line:
                    bbox_lines.append(stripped_line)
            
            # 解析边界框数据(格式:id x y width height)
            bbox_data = []
            for line in bbox_lines:
                parts = line.split()
                if len(parts) >=5:
                    bbox_data.append({
                        "元素ID": parts[0],
                        "X坐标": float(parts[1]),
                        "Y坐标": float(parts[2]),
                        "宽度": float(parts[3]),
                        "高度": float(parts[4])
                    })
            
            print(f"第{page}个SVG的边界框数据: {bbox_data}")
            page +=1

    # 退出Inkscape
    process.stdin.write("quit\n")
    process.stdin.flush()

# 执行转换与数据提取
create_image_data(LIST_OF_SVGs)

# 等待进程结束
process.wait()

关键修改说明

  • 移除shell=True:直接启动Inkscape进程,避免中间Shell层干扰输出捕获。
  • 行缓冲配置:bufsize=1让stdout按行缓冲,保证输出能实时读取。
  • stderr后台处理:单独线程读取错误输出,防止缓冲区满导致进程挂起。
  • 提示符识别:每次命令执行后读取到>提示符确认完成;query-all输出通过读取到下一个>来提取有效内容。
  • 临时文件自动清理:设置delete=True,避免临时文件残留。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 10:27:45