PythonでPSDファイルをJPEGやPNGに変換する

PythonでPSDファイルを読み込んで、別のファイルフォーマットで出力してみました。Pillow(PIL)やOpenCVを経由する方法も試してみました。

目次

  1. Pillowを使う場合
  2. psd-toolsを使う場合(コマンドライン変換)
  3. psd-toolsで読み込む場合(Pillowで再利用する)
  4. psd-toolsで読み込む場合(OpenCVで再利用する)

Pillowを使う場合

Adobe Photshop 2.5か3.0のファイルであれば、PillowでPSDファイルを読み込みできます。

プロ生ちゃん のサイトからダウンロードさせていただいたIXYさんによるイラストをモデルにして試してみます。元画像は、立ち絵A_170516.psd というファイル名のファイルです。

元の画像をtest.psdとして、Python/Pillowを使ってJPEGに変換してみます。

from PIL import Image

im = Image.open('test.psd')                               # 読み込み
im = im.resize((int(im.width*0.2), int(im.height*0.2))) # 縮小
im.save('test.jpg', quality=75)                         # 書き出し

非常に簡単なコードですね。

出力結果はこうなります。

Pillowでの出力例

psd-toolsを使う場合(コマンドライン変換)

psd-tools という、PSDファイルをサポートするモジュールがあります。

pipでインストールできます。

> pip install psd-tools

いちいちPythonを起動しなくても、コマンドラインで動作します。ここでは、test.psdをtest.jpgというJPEGファイルに変換してみます。

> psd-tools export test.psd test.jpg

オプションの指定ができるらしいのですが、それはよくわかりませんでした。

出力結果はこうなります。元画像のサイズが大きいので、出力したJPEGファイルをペイントで20%に縮小しました。

psd-toolsでの変換例

psd-toolsで読み込む場合(Pillowで再利用する)

psd-toolsでPSDファイルを読み込んで、読み込んだデータをPillowに渡してみます。

psd-toolsのcompositeというメソッドで、レイヤーの統合ができます。

test.psd を読み込んで、Pillowで縮小して test.jpg に出力するコードです。

from PIL import Image
from psd_tools import PSDImage

psd = PSDImage.open('test.psd')  # 読み込み
im = psd.composite()             # 変換
im = im.resize((int(im.width*0.2), int(im.height*0.2))) # 縮小
im.save('test.jpg', quality=75)  # 出力

出力結果はこうなります。

psd-toolsでの変換例(Pillow)

psd-toolsで読み込む場合(OpenCVで再利用する)

psd-toolsでPSDファイルを読み込んで、読み込んだデータをOpenCVに渡してみます。

手順はPillowの場合とほぼ同じですが、NumPy行列に変換するためにはnumpyというメソッドを使用します。

import cv2
from psd_tools import PSDImage

psd = PSDImage.open('test.psd')  # 読み込み
im = psd.numpy()                 # 変換
im = cv2.resize(im , (int(im.shape[1]*0.2), int(im.shape[0]*0.2))) # 縮小
cv2.imwrite('test.jpg', im)

あれ? 出力結果が真っ黒になってしまいました。

psd-toolsでの変換例(OpenCV)失敗1

画素のデータがfloatになっているので、JPEGとかPNGでそのまま出力すると黒くなるわけですね。

ということで、intに変換します。

import cv2
import numpy as np
from psd_tools import PSDImage

psd = PSDImage.open('test.psd')  # 読み込み
im = psd.numpy()                 # 変換
im = cv2.resize(im , (int(im.shape[1]*0.2), int(im.shape[0]*0.2))) # 縮小
im = np.clip(im * 255, 0, 255).astype(np.uint8)                    # 整数に変換
cv2.imwrite('test.jpg', im)

あれれ? 色が変ですね。

psd-toolsでの変換例(OpenCV)失敗1

これはNumPy行列のRGBが異なっているというパターンですね。

ということで、RGBの入れ替えを追加します。

import cv2
import numpy as np
from psd_tools import PSDImage

psd = PSDImage.open('test.psd')  # 読み込み
im = psd.numpy()                 # 変換
im = cv2.resize(im , (int(im.shape[1]*0.2), int(im.shape[0]*0.2))) # 縮小
im = np.clip(im * 255, 0, 255).astype(np.uint8)                    # 整数に変換
im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)                           # RGBの入れ替え
cv2.imwrite('test.jpg', im)

うまくできました。

psd-toolsでの変換例(OpenCV)成功

広告

Pythonで画像処理カテゴリの投稿