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

如何在像素与Graphviz尺寸/坐标间进行转换?

解决PNG渲染图坐标与Graphviz JSON坐标的转换问题

1. 核心坐标系差异

  • PNG像素坐标系:以左上角为原点(0,0),向右为x轴正方向,向下为y轴正方向,对应你提到的167×251尺寸。
  • Graphviz JSON的bb(边界框)坐标系:以左下角为原点(0,0),向右为x轴正方向,向上为y轴正方向,对应117×180的实际绘制区域尺寸。JSON里的bb格式为[x_min, y_min, x_max, y_max],通常x_min和y_min为0,宽度= x_max - x_min,高度= y_max - y_min。

2. 坐标转换公式

假设:

  • PNG点击坐标为(png_x, png_y)
  • JSON的bb参数为bb_x0, bb_y0, bb_x1, bb_y1,计算得bb_width = bb_x1 - bb_x0,bb_height = bb_y1 - bb_y0
  • PNG宽png_width,高png_height

转换步骤:

  1. 反转PNG的y坐标(适配JSON的y轴方向):png_y_reversed = png_height - png_y
  2. 计算缩放比例:scale_x = bb_width / png_width,scale_y = bb_height / png_height
  3. 映射到JSON坐标系:
    • json_x = bb_x0 + png_x * scale_x
    • json_y = bb_y0 + png_y_reversed * scale_y

3. Python实现示例(基于Tkinter)

import json
from tkinter import Tk, Canvas, PhotoImage

# 加载Graphviz JSON数据
with open('graph.json', 'r') as f:
    graph_data = json.load(f)

# 解析bb参数
bb = graph_data['bb'].split(',')
bb_x0, bb_y0, bb_x1, bb_y1 = map(float, bb)
bb_width = bb_x1 - bb_x0
bb_height = bb_y1 - bb_y0

# PNG图片尺寸(可替换为从图片文件读取的实际尺寸)
png_width = 167
png_height = 251

def on_click(event):
    # 获取PNG点击坐标
    png_x, png_y = event.x, event.y
    
    # 转换为JSON坐标系坐标
    png_y_reversed = png_height - png_y
    json_x = bb_x0 + png_x * (bb_width / png_width)
    json_y = bb_y0 + png_y_reversed * (bb_height / png_height)
    
    # 匹配点击的节点
    for obj in graph_data['objects']:
        if obj['type'] == 'node':
            node_bb = obj['bb'].split(',')
            nx0, ny0, nx1, ny1 = map(float, node_bb)
            if nx0 <= json_x <= nx1 and ny0 <= json_y <= ny1:
                print(f"点击节点: {obj['name']}")
                return
    print("未命中任何节点")

# 展示图片并绑定点击事件
root = Tk()
canvas = Canvas(root, width=png_width, height=png_height)
canvas.pack()
img = PhotoImage(file='graph.png')
canvas.create_image(0, 0, anchor='nw', image=img)
canvas.bind('<Button-1>', on_click)

root.mainloop()

4. 关键注意事项

  • 确保JSON文件通过dot -Tjson input.dot > graph.json或-Tjson0生成,两种格式的bb与节点坐标逻辑一致。
  • PNG的尺寸包含Graphviz自动添加的边距,而bb仅对应实际图形区域,因此直接按比例缩放即可完成映射。
  • 节点的bb同样为[x_min, y_min, x_max, y_max],判断转换后的坐标是否落在该矩形内即可识别点击节点。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.20 08:25:07