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

如何将draw.io导出PNG文件中的压缩数据转换为XML格式

解决方法

你当前从tEXt块提取到的第二个元素是经过URL编码的mxfile结构,其中<diagram>标签包裹的内容是经过Base64编码+Deflate压缩的绘图数据,按以下步骤解码即可得到完整XML:

import png
import urllib.parse
import base64
import zlib
from xml.etree import ElementTree as ET

filename = "./image3.png"
# 读取PNG所有块
reader = png.Reader(filename)
chunks = list(reader.chunks())

# 定位tEXt块中key为mxfile的内容
mxfile_encoded = None
for chunk_type, chunk_data in chunks:
    if chunk_type == b"tEXt":
        parts = chunk_data.split(b"\x00", 1)
        if parts[0] == b"mxfile":
            mxfile_encoded = parts[1].decode("utf-8")
            break

if not mxfile_encoded:
    raise ValueError("PNG中未找到draw.io存储的mxfile数据")

# 第一步:URL解码得到外层mxfile结构
outer_mxfile_str = urllib.parse.unquote(mxfile_encoded)
outer_root = ET.fromstring(outer_mxfile_str)
diagram_elem = outer_root.find("diagram")
compressed_b64 = diagram_elem.text.strip()

# 第二步:Base64解码+zlib解压得到内部mxGraphModel结构
compressed_data = base64.b64decode(compressed_b64)
# wbits=-15 代表使用Raw Deflate格式,适配draw.io的压缩规则
xml_inner = zlib.decompress(compressed_data, wbits=-15).decode("utf-8")

# 组装完整XML
full_xml = f"""<?xml version="1.0" encoding="UTF-8"?>
{ET.tostring(outer_root, encoding="unicode").split("><diagram")[0]}>
  <diagram id="{diagram_elem.get('id')}" name="{diagram_elem.get('name')}">
    {xml_inner}
  </diagram>
</mxfile>
"""

print(full_xml)

代码说明

  • 兼容tEXt/zTXt两种块格式,无论draw.io导出时选择压缩还是非压缩存储,都能正常读取
  • 最终输出的XML结构可直接导入draw.io编辑使用

内容的提问来源于stack exchange,提问作者Igor L.

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.26 04:15:02