psd-toolsとは
psdファイルをpythonで読み込む為のpythonパッケージです
レイヤーごとの内容を取得できます。
インストール
pipで入ります
pip install psd-tools
ファイル全体
ファイルを読み込む
下のような背景+4レイヤーからなるpsdファイルを読んでみます
import psd_tools
psd = psd_tools.PSDImage.open('./sample.psd')
psd
PSDImage(mode=ColorMode.RGB size=300x200 depth=8 channels=3)
[0] PixelLayer('背景' size=300x200)
[1] TypeLayer('テキストレイヤー' size=95x11)
[2] PixelLayer('黄色四角' size=131x72)
[3] ShapeLayer('長方形ツール' size=143x57)
[4] ShapeLayer('赤線' size=119x98)
表示する
上記のpsdオブジェクトのcomposite()メソッドでファイル全体を画像に変換してくれます
psd.composite()
画像として書き出す
composite()してからsave()メソッドで画像として保存できます
psd.composite().save('./sample.png')
値をnumpy arrayとして取得する
画像のRGBの値をnumpy arrayとして取得できます
arr = psd.numpy()
print(arr.shape)
arr
(200, 300, 3)
array([[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
...,
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]],
...,
[[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
...,
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]]], dtype=float32)
中身は普通にRGBなので表示してやると同じ画像になります
import matplotlib.pyplot as plt
plt.imshow(arr)
plt.show()
レイヤーごと
レイヤーごとに表示する
psdオブジェクトはiterableで、インデックス指定またはiterでそれぞれのレイヤーを取得できます。for文で回すと下のレイヤーから順に出てきます。
for k, layer in enumerate(psd):
print('{}: {}'.format(k, layer))
print('offset: {}'.format(layer.offset))
display(layer.composite())
PixelLayer、TextLayer、ShapeLayerがそれぞれ区別されて読み込まれているのが分かります。また、描画がある場所だけ表示するようになっているので、layerごとにoffset, height, widthが設定されています。
レイヤーの値を取得する
レイヤーの値もnumpy arrayとして取得できます
layer = psd[4]
arr = layer.numpy()
print(arr.shape)
arr[:80, :100]
レイヤーは透明度が設定されているので4チャンネルが取得されます。ShapeLayerはRGBの値は同じで透明度のみ変更されているので以下のように最後のチャンネルのみ変わります。
(98, 119, 4)
array([[[1., 0., 0., 0.],
[1., 0., 0., 0.],
[1., 0., 0., 0.],
...,
[1., 0., 0., 0.],
[1., 0., 0., 0.],
[1., 0., 0., 0.]],
...,
[[1., 0., 0., 0.],
[1., 0., 0., 0.],
[1., 0., 0., 0.],
...,
[1., 0., 0., 1.],
[1., 0., 0., 1.],
[1., 0., 0., 1.]]], dtype=float32)
ファイルの書き換えは出来ないっぽい
便利なのでこれを使ってpsd形式の込み入った図を作ろうかと思ったんですが、書き換えには対応していないようです。やりとりを見た感じだとpsd形式のフォーマットが公開されていないので独自に解析してやるしかないのが障害になってるようです。
https://github.com/psd-tools/psd-tools/issues/84