PythonからCOMオブジェクトを扱う / HoudiniからPhotoshopをちょっと操作する


この記事はTakumi Akashiro ひとり Advent Calendar 2020の10日目の記事です。

今日はHoudiniからPhotoshopを起動して操作します。
興味のある方はどうぞ。

始めに

pythonでCOMオブジェクトを使いたい瞬間はありませんか?
ありませんね。エクセルとか操作したくなったら、pyWin32とか使うし……
いやでも、pyWin32ってDCCツールに組み込みずらいし……と嘆いている方に朗報です!

簡単にCOMオブジェクトを扱える拡張モジュールがあるんです!
その名もcomtypes


comtypes · PyPI

comtypes は、ctypes FFI ライブラリをベースにした Python の軽量な COM パッケージで、
10000 行以下のコードで構成されています (テストはカウントされていません)。

ビルドされたバイナリも使っておらず、依存関係も標準モジュール以外はないので、
DCCツールにも組み込みやすいのもいいですね。

通常の導入方法

いつも通りpip install comtypesですね。

MayaとかHoudiniとか

pip install -t <pythonpath> comtypes
で適当なパスが通ったディレクトリにインストールします。

無法ですが、Zipを落としてきて、展開して適切なフォルダを適当に投げ入れても動きます。
というか、今後pipで管理する予定が無いなら、不要なegg-infoとかbinフォルダはいらないので、
pipを使わずに適当に入れたほうが無駄なファイルは減りますね。

3系は元の構文が2系ベースで書かれていて、そのままだとSyntaxErrorで動かないので、
pipを通すか自前で2to3をかける必要がありました。

無法なことをやるなら、まあsetup.pyには目を通しておいたほうがいいとは思いますね。

試す

ではHoudiniからPhotoshopをCOMオブジェクト経由で起動し、適当なファイルを保存するスクリプトを試してみます。

#!python
# encoding:utf-8

import comtypes.client
import gc

def main():
    photoshop = comtypes.client.CreateObject("Photoshop.Application")
    document = photoshop.Documents.Add()

    color = comtypes.client.CreateObject("Photoshop.SolidColor")
    color.RGB.Red = 255
    color.RGB.Green = 0
    color.RGB.Blue = 0

    document.Selection.SelectAll()
    document.Selection.Fill(color)

    document.SaveAs("D:\COMControl_Sample.psd")
    photoshop.Quit()

    # 関数が終了すればオブジェクトが破棄されて、
    # 解放されると思うが、念のために明示的にガベコレする。
    del photoshop, document, color
    gc.collect()


main()

出来ましたね!DドライブにPSDファイルができてます。

締め

最初はCOMオブジェクトを簡単に使える拡張モジュールを紹介するつもりだったんですが、
調べて記事に起こしていくうちに、思った以上に有用になってしまって自分でもびっくりしています。

……PhotoshopってCOMオブジェクト経由でコントロールできるんですね…初めて知ったわ…

追記

でもPhotoshopをPythonから操作するなら、正直にphotoshop-python-apiを使うほうがいいかもですね……
photoshop-python-api · PyPI

こっちもrequirementsを読む限りはcomtypesを使ってるみたいですん。