Files
RoRD-Layout-Recognation/tools/layout2png.py
2025-06-09 01:42:47 +08:00

88 lines
3.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import gdstk
import cairosvg
import argparse
import os
def convert_layout_to_png_via_svg(layout_path, png_path, cell_name=None, pixels_per_unit=10):
"""
通过先生成 SVG 再转换为 PNG 的方式,将 GDSII 或 OASIS 文件光栅化。
此版本修正了 write_svg 的参数错误,兼容性更强。
参数:
layout_path (str): 输入的版图文件路径(.gds 或 .oas
png_path (str): 输出的 PNG 文件路径。
cell_name (str, optional): 需要转换的单元名称。如果为 None则使用顶层单元。
pixels_per_unit (int, optional): 版图数据库单位到像素的转换比例,控制图像分辨率。
"""
print(f"正在从 '{layout_path}' 读取版图文件...")
# 1. 加载版图文件
_, extension = os.path.splitext(layout_path)
extension = extension.lower()
if extension == '.gds':
lib = gdstk.read_gds(layout_path)
elif extension == '.oas':
lib = gdstk.read_oas(layout_path)
else:
raise ValueError(f"不支持的文件类型: '{extension}'。请输入 .gds 或 .oas 文件。")
if cell_name:
cell = lib.cells[cell_name]
else:
top_cells = lib.top_level()
if not top_cells:
raise ValueError("错误:版图文件中没有找到顶层单元。")
cell = top_cells[0]
print(f"未指定单元名称,自动选择顶层单元: '{cell.name}'")
# 2. 将版图单元写入临时的 SVG 文件 (已移除无效的 padding 参数)
temp_svg_path = png_path + ".temp.svg"
print(f"步骤 1/2: 正在将单元 '{cell.name}' 转换为临时 SVG 文件...")
cell.write_svg(
temp_svg_path # 隐藏默认字体,避免影响边界
)
# 3. 使用 cairosvg 将 SVG 文件转换为 PNG
print(f"步骤 2/2: 正在将 SVG 转换为 PNG...")
# 获取单元的精确边界框
bb = cell.bb()
if bb is None:
raise ValueError(f"单元 '{cell.name}' 为空或无法获取其边界框。")
# 根据边界框和分辨率计算输出图像的宽度
width, height = bb[1] - bb[0]
output_width = width * pixels_per_unit
cairosvg.svg2png(url=temp_svg_path, write_to=png_path, output_width=output_width)
# 4. 清理临时的 SVG 文件
os.remove(temp_svg_path)
print(f"成功!图像已保存至: '{png_path}'")
if __name__ == "__main__":
parser = argparse.ArgumentParser(
description="将 GDSII (.gds) 或 OASIS (.oas) 版图文件转换为 PNG 图像 (通过SVG)。",
epilog="示例: python rasterize.py -i my_chip.oas -o my_chip.png -ppu 20"
)
parser.add_argument('-i', '--input', type=str, required=True, help="输入的版图文件路径 (.gds 或 .oas)。")
parser.add_argument('-o', '--output', type=str, help="输出的 PNG 文件路径。如果未提供,将使用输入文件名并替换扩展名为 .png。")
parser.add_argument('-c', '--cell', type=str, default=None, help="要转换的特定单元的名称。默认为顶层单元。")
parser.add_argument('-ppu', '--pixels_per_unit', type=int, default=10, help="每微米um的像素数用于控制输出图像的分辨率。")
args = parser.parse_args()
if not args.output:
base_name = os.path.splitext(os.path.basename(args.input))[0]
args.output = f"{base_name}.png"
print(f"未指定输出路径,将自动保存为: '{args.output}'")
try:
convert_layout_to_png_via_svg(
layout_path=args.input,
png_path=args.output,
cell_name=args.cell,
pixels_per_unit=args.pixels_per_unit
)
except Exception as e:
print(f"\n处理失败: {e}")