LoginSignup
1
0

MatplotlibとShapelyとgdstkを使用して日本語をポリゴン化&GDSII化

Posted at

はじめに

MatplotlibとShapelyを使用したテキストのポリゴン化と、gdstk を用いたGDSIIファイル形式への書き出しについて紹介します。

に実行結果は載せています。

以下にその方法を説明します。

必要なライブラリのインポート

まず、必要なライブラリをインポートします。

from matplotlib.textpath import TextPath
from shapely.geometry import Polygon
from matplotlib import font_manager as fm
import matplotlib.pyplot as plt
  • TextPathMatplotlibでテキストからパスを生成するために使用します。
  • font_manager はフォントのプロパティを管理します。
  • PolygonShapelyでポリゴンを扱うためのクラスです。

フォントプロパティの設定

テキストをポリゴン化するためには、フォントの設定が必要です。ここでは、日本語フォントのパスを指定します。

fp = fm.FontProperties(fname='./NotoSerifJP-Regular.otf')

日本語のフォントは、

から好きなフォントのファイルを取得してます。

FontProperties にはフォントファイルへのパスを指定します。例では、Noto Serif JPフォントを使用しています。

google colab の方では、

import gdown # https://github.com/wkentaro/gdown
# download data
fileURL="https://drive.google.com/file/d/1ZSovgMRADTRnLAk3K5YlnjcJx1HVeTtF/view?usp=sharing" # download NotoSerifJP-Regular.otf from my drive
localfile="NotoSerifJP-Regular.otf"
gdown.download(fileURL, localfile, quiet=False, fuzzy=True)

のように、私のgoogle drive から、gdown で取得して使うような設定にしてます。

テキストからポリゴンを生成する関数

テキストを受け取り、それをポリゴンに変換する関数を定義します。

def text_to_polygons(text, fontsize, fontprop):
    # テキストからTextPathを生成
    tp = TextPath((0, 0), text, size=fontsize, prop=fontprop)

    # TextPathからポリゴンを生成
    polygons = []
    for path in tp.to_polygons(closed_only=False):
        if len(path) == 0:
            continue
        exterior = path
        polygon = Polygon(exterior)
        polygons.append(polygon)
    return polygons

この関数は、テキストから TextPath を生成し、そのパスを Polygon オブジェクトに変換します。

コード全文

ジオメトリの生成と確認

from matplotlib.textpath import TextPath
from shapely.geometry import Polygon
from matplotlib import font_manager as fm
import matplotlib.pyplot as plt

# フォントプロパティの設定
fp = fm.FontProperties(fname='./NotoSerifJP-Regular.otf')  # 日本語フォントへのパスを指定

def text_to_polygons(text, fontsize, fontprop):
    """
    テキストから外周と内部の穴を持つポリゴンを生成する。

    Parameters:
    text (str): テキスト。
    fontsize (int): フォントサイズ。
    fontprop (FontProperties): フォントプロパティ。

    Returns:
    list: Polygonオブジェクトのリスト。
    """
    tp = TextPath((0, 0), text, size=fontsize, prop=fontprop)
    polygons = []

    for path in tp.to_polygons(closed_only=False):
        if len(path) == 0:
            continue
        exterior = path  # 外周
        polygon = Polygon(exterior)  # 内部の穴はないと仮定
        polygons.append(polygon)

    return polygons

# 使用例
text_polygons = text_to_polygons("2023年12月18日 製作", 100, fp)

# プロット
fig, ax = plt.subplots()
for polygon in text_polygons:
    x, y = polygon.exterior.xy
    ax.plot(x, y, color="black")

    for interior in polygon.interiors:
        x, y = interior.xy
        ax.plot(x, y, color="red")

ax.set_aspect('equal', adjustable='box')
plt.show()

実行結果

スクリーンショット 2023-12-18 11.01.18.png

GDSIIファイルへの書き出し

# LSI回路のジオメトリを作成
lib = gdstk.Library()
cell = lib.new_cell("IMAGER_ARRAY")

tag = {
    "pixel": {"layer": 1, "datatype": 1},
    "int": {"layer": 5, "datatype": 5},
    "ext": {"layer": 10, "datatype": 10},
}

# Convert shapely geometries to gdstk polygons
for polygon in text_polygons:
    coords = polygon.exterior.coords
    cell.add(gdstk.Polygon(coords, **tag["ext"]))
    for interior in polygon.interiors:
        print ("interior")
        coords = interior.coords
        cell.add(gdstk.Polygon(coords, **tag["int"]))

# Save the GDS file
outgdsfile="japanese.gds"
lib.write_gds(outgdsfile)

# GDSファイルに保存
lib.write_gds(outgdsfile)
plot_gds_onlypoly(outgdsfile, debug=False)

実行例

スクリーンショット 2023-12-18 11.01.25.png

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0