ag-psd は、JavaScript(Node.js とブラウザ)で PSD を読み書きできる、MIT ライセンスのライブラリです。
Photoshop が無くても、レイヤーの一覧を取り出したり、レイヤーを組んだ PSD を作ったり、文字レイヤーの文字を書き換えたりできます。
- 入れ方:npm i ag-psd canvas(Node.js で画像を扱うには canvas も要る)
- 読む:readPsd(バッファ)、書く:writePsdBuffer(オブジェクト)
- 文字を書き換えたら invalidateTextLayers: true を付ける(Photoshop で開いたときに描き直させる)
- RGB・8bit の PSD だけ。CMYK は RGB に変換して読み、PSB(大きい形式)は使えない
この記事の結果は、2026年9月29日に Windows 11 で ag-psd 31.0.2・canvas 3.2.3・Node.js 24.15.0 を使って試したものです。
読み込みの確認には、psd-tools の公式リポジトリにあるテスト用の PSD(MIT)を使いました。
入れる
npm init -y
npm i ag-psd canvasNode.js では、require(‘ag-psd/initialize-canvas’) で、画像を扱う準備をしてから使います。
レイヤーの一覧を読む
const fs = require('fs');
require('ag-psd/initialize-canvas');
const { readPsd } = require('ag-psd');
const psd = readPsd(fs.readFileSync(process.argv[2]), { skipLayerImageData: true, skipThumbnail: true });
console.log(`${psd.width}x${psd.height}`);
function walk(layers, depth) {
for (const l of layers || []) {
const kind = l.children ? 'グループ' : l.text ? '文字' : l.adjustment ? '調整:' + l.adjustment.type : l.placedLayer ? 'スマートオブジェクト' : 'ピクセル';
console.log(' '.repeat(depth) + `- ${l.name}(${kind})` + (l.text ? ` 「${l.text.text}」` : ''));
walk(l.children, depth + 1);
}
}
walk(psd.children, 0);skipLayerImageData: true にすると、画像のデータを読まないので、一覧を取るだけなら速くなります。
テスト用の PSD を読むと、次のように出ました(一部)。
256x256
- Background(ピクセル)
- linked-png(スマートオブジェクト)
- linked-psd(スマートオブジェクト)
- embedded-png(スマートオブジェクト)
256x256
- Background(ピクセル)
- Rectangle 1(ピクセル)
- Brightness/Contrast 1(調整:brightness/contrast)
- Levels 1(調整:levels)
- Curves 1(調整:curves)
- Hue/Saturation 1(調整:hue/saturation)文字レイヤーは l.text.text で文字を、調整レイヤーは l.adjustment.type で種類を取り出せました。
PSDを作る
白い背景に、グループと2つの四角のレイヤー(片方は不透明度50%)を入れた PSD を作ります。
const fs = require('fs');
const { createCanvas } = require('canvas');
require('ag-psd/initialize-canvas'); // Node で画像を扱うための準備
const { writePsdBuffer } = require('ag-psd');
function rect(w, h, color) {
const c = createCanvas(w, h);
const ctx = c.getContext('2d');
ctx.fillStyle = color;
ctx.fillRect(0, 0, w, h);
return c;
}
const psd = {
width: 400,
height: 300,
children: [
{ name: '背景', canvas: rect(400, 300, '#ffffff') },
{ name: 'パーツ', children: [
{ name: '赤い四角', left: 40, top: 40, canvas: rect(120, 80, '#e03c31') },
{ name: '青い四角', left: 200, top: 120, canvas: rect(150, 120, '#2f6fd6'), opacity: 0.5 },
]},
],
canvas: rect(400, 300, '#ffffff'), // 合成済みのプレビュー(簡略化)
};
fs.writeFileSync('out.psd', writePsdBuffer(psd));
console.log('書き出した', fs.statSync('out.psd').size, 'バイト');書き出した 22832 バイトできた PSD を、Python の psd-tools でも読み込めるか確かめました。
400 300
背景 pixel 255
パーツ group 255
赤い四角 pixel 255
青い四角 pixel 128レイヤーの名前・グループ・不透明度(255 の半分の 128)が、そのまま読めました。
ここでは合成済みのプレビュー(psd.canvas)を白一色にしているので、プレビューを使うソフトでは白く見えます。
正しいプレビューが要るときは、自分で合成した画像を canvas に入れます。
文字レイヤーの文字を書き換える
const fs = require('fs');
require('ag-psd/initialize-canvas');
const { readPsd, writePsdBuffer } = require('ag-psd');
const psd = readPsd(fs.readFileSync(process.argv[2]));
let count = 0;
(function walk(layers) {
for (const l of layers || []) {
if (l.text) { l.text.text = l.text.text.replace(/Line/g, '行'); count++; }
walk(l.children);
}
})(psd.children);
if (process.argv[4] === '--drop-resources') delete psd.imageResources;
// 文字を書き換えたら、Photoshop で開いたときに描き直させる
fs.writeFileSync(process.argv[3], writePsdBuffer(psd, { invalidateTextLayers: true }));
console.log('文字レイヤー', count, '個を書き換えた');文字を書き換えたら、invalidateTextLayers: true を付けて書き出します。
README によると、ag-psd は文字レイヤーの画像を描き直さないので、Photoshop で開くと更新を求める画面が出ます。
そこで「Update」を選ぶと、Photoshop が文字を描き直します(「No」を選ぶと文字レイヤーが壊れた状態で残る)。
書き出しでエラーになった
テスト用の text.psd をそのまま書き出すと、次のエラーで止まりました。
Error: Invalid boolean value: undefined, key: enab
at writeOSType (...\ag-psd\dist\descriptor.js:680:23)
...
at Object.write (...\ag-psd\dist\imageResources.js:584:48)止まったのは、レイヤーではなく、PSD 全体の付加情報(image resources)を書くところでした。
psd.imageResources を消してから書き出すと、書き出せて、ag-psd と psd-tools の両方で、書き換えた文字(行 1 行 2 行 3 and text)を読めました。
ただし、付加情報には解像度などの設定も入っているので、消すと失われるものがあります。
読み込んで書き出す使い方は、PSD によっては失敗するので、元のファイルは必ず残しておきます。
できないこと
| 項目 | README の説明 |
|---|---|
| 色のモード | RGB 以外(CMYK・Lab など)は、読むときに RGB に変換。書けるのは RGB だけ |
| ビット数 | 16bit には非対応 |
| PSB | 大きい形式(PSB)には非対応 |
| 文字レイヤー | 実装は途中。縦書きの書き出しは壊れることがある。段落・文字スタイルは非対応 |
| 描き直し | 描画オプション・ベクター・文字を変えても、画像の描き直しはしない |
| パターン | Photoshop の多くのファイルが使う圧縮のパターンは非対応 |
README には、利用者が送ってきた PSD を扱うときは、大きさやビット数を先に確かめるよう、例とともに書かれています。
Pythonのpsd-toolsとの使い分け
| ag-psd | psd-tools | |
|---|---|---|
| 言語 | JavaScript(Node.js・ブラウザ) | Python |
| 読む | ○ | ○ |
| 新しく作る | ○(レイヤーを組める) | △(基本的な編集のみ) |
| 見た目の合成 | しない(自分で行う) | 一部の調整レイヤー・効果まで対応 |
psd-tools の使い方は、psd-toolsの使い方で紹介しています。
psd-tools で見た目が変わる PSD の見分け方は、psd-toolsで書き出せないPSDの見分け方で紹介しています。
まとめ
- npm i ag-psd canvas で入れ、readPsd と writePsdBuffer で読み書きする
- レイヤー・グループ・不透明度は psd-tools でもそのまま読めた
- 文字を変えたら invalidateTextLayers: true。Photoshop で開いたら「Update」
- 読み込んだ PSD の書き出しは失敗することがある。元のファイルは残す
参考:ag-psd の README(31.0.2)と、当方での実行結果(2026年9月29日)。
