そのPSD、レイヤー消えてます — ibisPaint と Procreate の書き出しの罠
投稿 最終更新
この記事の読み手は、絵を発注する側と、iPadで描いてPSDを納品する側です。「なんでレイヤーが消える?」と検索したときに、開いたまま読める記録にしたつもりです。製品の宣伝ではありません。株式会社佐野組がゲーム開発の案件で踏んだ事故のレポートです。
先に結論
ibisPaint では、キャンバス画面から書き出すと「Preserve Layers」(レイヤーを保持)の項目そのものが出ず、レイヤーが結合された状態で出ます。レイヤーを残すときはマイギャラリーから作品を選び、PSD (Preserved Layers)(PSD(レイヤーを保持))で書き出します。
Procreate では、レイヤーを残す形式は PSD です。JPEG / PNG / TIFF はいずれも flatten(統合)されます。Share Layers は形式を問わず、表示中のレイヤーだけが書き出される、と公式に書かれています。非表示レイヤーが PSD の Share Image でどうなるかは、公式に「visibility を保持する」と「表示中だけ書き出される」の両方があり、こちらでは実機確認していません。
発注のときに添える一文の例と、受け取る側が開かずにレイヤーの有無を見るコードは、下にあります。コードは飛ばして大丈夫です。
事故
ゲーム開発の案件で、UIの配置指定をPSDで受け取りました。開くとレイヤーが1枚に統合されていて、要素ごとの位置・サイズが取れませんでした。
最初は納品の経路(Docker経由の取り込み)で加工ミスがあったのでは、と疑いました。追ったところ、コードは fs.linkSync / fs.copyFileSync だけで、画像ライブラリは使っていませんでした。バイト列はそのまま通っていました。原因はアプリ側の書き出しでした。
届いたファイルは 3840×2160 で、後述の確認では layer_info_len と layer_count がどちらも 0 でした。直接の原因は、ibisPaint のキャンバス画面からの書き出し経路でした。
ibisPaint の罠
出典は ibisPaint 公式の講義ページです。
マイギャラリーからの手順について、公式には次のように書かれています。
“Tap ①Share button and choose ②"PSD (Preserved Layers)" or "PSD (Flattened Layer)" according to the use.”
(共有ボタンを押し、用途に応じて「PSD(レイヤーを保持)」または「PSD(レイヤーを統合)」を選ぶ、という意味です。)
“When using an application that can edit PSD files, such as PC it's recommended exporting with "PSD (Preserved Layers)"”
(PCなどPSDを編集できるアプリ向けには「PSD(レイヤーを保持)」が推奨、という意味です。印刷原稿向けには、ブレンドモードによる色のずれを避けるため Flattened が案内されています。)
核心は、次の一文でした。
“When saving from the canvas screen, this item is not shown and the artwork is exported with 'Preserve Layers' turned off.”
(キャンバス画面から保存すると、この項目は表示されず、レイヤー保持はオフのまま書き出される、という意味です。)
描き終わってそのまま共有する、という自然な操作が、そのまま罠になっていました。今回受け取ったファイルも、この経路でした。
Procreate の場合
出典は Procreate 公式ハンドブックの Share です。
“Tap Actions → Share → PSD, then select a destination for your file.”
(Actions → Share → PSD を選び、保存先を選ぶ、という意味です。)
“This will save your image into the standard format used by Adobe® Photoshop®, preserving all your layers, layer names, opacity, visibility and blend modes.”
(Adobe Photoshop の標準形式で保存し、レイヤー・名前・不透明度・可視性・ブレンドモードを保持する、という意味です。)
一方、JPEG / PNG / TIFF については、いずれも flatten(レイヤー統合)されると書かれています。Share Layers では、PDF(レイヤーごとに1ページ)、PNG(レイヤーごとのフォルダ)、アニメーション形式などが案内されています。
形式を問わない一文もあります。
“Regardless of the format you choose, only visible layers will be exported.”
(どの形式を選んでも、表示中のレイヤーだけが書き出される、という意味です。)
同じ公式ページには、PSDについて「visibility を保持する」とも、「表示中のレイヤーだけが書き出される」とも書かれています。非表示レイヤーが PSD の Share Image でどう扱われるかは、この2文だけでは切り分けきれません。こちらでは iPad 実機での確認はしていません。公式に両方ある、という事実だけを残します。
発注時に添える一文(防げた実例)
今回の切れ目を知ったあとなら、発注文に次のような一文を添えておけば防げた、という実例です。命令ではなく、こちらが後から書いた控えです。
PSDでレイヤーを残す場合は、ibisPaintならマイギャラリーから「PSD(レイヤーを保持)」で書き出してください。キャンバス画面からの書き出しだとレイヤーが統合されます。Procreateなら Actions → Share → PSD を選び、JPEG / PNG / TIFF ではレイヤーが残りません。
受け取る側の確認(コード・飛ばしてOK)
ここから下のコードは飛ばして大丈夫です。発注文の一文と、ibisPaint/Procreateの手順だけで足ります。
Photoshopがなくても、PSDのバイナリを読めばレイヤーの有無は分かります。今回の事故も、これで確定させました。構造の出典は Adobe の Photoshop File Formats Specification です。並びは File Header → Color Mode Data → Image Resources → Layer and Mask Information → Image Data です。レイヤーやマスクが無いとき、Layer and Mask Information は長さゼロを示す4バイトだけになります(PSBは8バイト)。レイヤー数は符号付き2バイトで、負のときは絶対値が枚数で、先頭のアルファが結合透明度を持つ、と仕様に書かれています。
この案件で使った Python の骨格は、次のとおりです。
import struct
with open('received.psd', 'rb') as f:
f.read(4) # signature '8BPS'
struct.unpack('>H', f.read(2))[0] # version
f.read(6) # reserved
channels = struct.unpack('>H', f.read(2))[0]
height = struct.unpack('>I', f.read(4))[0]
width = struct.unpack('>I', f.read(4))[0]
f.read(4) # depth + color mode
f.read(struct.unpack('>I', f.read(4))[0]) # color mode data
f.read(struct.unpack('>I', f.read(4))[0]) # image resources
struct.unpack('>I', f.read(4))[0] # layer & mask info length
layer_info_len = struct.unpack('>I', f.read(4))[0]
layer_count = struct.unpack('>h', f.read(2))[0]
print(width, height, layer_info_len, layer_count)
layer_info_len と layer_count がどちらも 0 なら、そのPSDはレイヤー情報を持っていない(統合済み)と読みました。届いたファイルは 3840×2160 で、この2つがどちらも 0 でした。
今回の切れ目
- 受け取ったUI配置のPSDは、レイヤーが統合されていました。
- 納品経路のコードはバイト列の素通りでした。画像ライブラリは使っていませんでした。
- 直接の原因は、ibisPaint のキャンバス画面からの書き出しでした。
- レイヤーを残す ibisPaint の経路は、マイギャラリー →
PSD (Preserved Layers)です。 - Procreate でレイヤーを残す形式は PSD です。JPEG / PNG / TIFF は統合されます。
- 公式には「visibility を保持」と「表示中だけ書き出す」の両方があります。非表示レイヤーの実機確認はしていません。
- 発注時の一文と、受け取り側のヘッダ確認で、同じ事故は止められる、というのが今回の切れ目です。
スクリーンショットは載せていません。メニュー文言は公式の英語表記と、その日本語訳に寄せました。アプリの画面は更新されるので、迷ったら公式の講義・ハンドブックを開くのが安全です。