
無料Photoshop代替の開発記
再読込を確かめる
PSDやPSBが開くだけでなく、保存して再び読むと編集情報がどこまで残るかを調べます。新しいAI人物写真から二つのレイヤーを作り、Photoshotで両形式を個別に往復しました。
AI生成の動作例用写真。編集画面と出力画像は実際のPhotoshotで作成しました。
ソースから始める。
開けることと編集可能な保存は違う
合成画像が見えても一枚に統合されていれば元の編集構造は戻っていません。名前・順序・表示・不透明度、マスク・文字・効果を別々に確認する必要があります。今回は二つの画像レイヤーの基本属性を対象にしました。
運用版psd-codec.tsはvendor/psd-codec.mjsの読み書きを使い、Photoshot文書へ変換します。形式の解析とアプリの文書モデルへの接続は別の作業です。この運用作業本と公開リポジトリーの対応範囲を同一とは説明しません。
メタデータの保持と意味の再現を分ける
psd-metadata.tsは通常のオブジェクトを再帰的に保持し、バイト配列をBase64と型名で包みます。canvas・imageData・rawData・childrenなどはこのコピーから除外されます。何でも丸ごとコピーせず、別経路で再構築する部分を分けています。
メタデータの存在だけで効果の描画一致や全文字機能の再編集を証明できません。psd-resources.tsもリソース領域と長さを検査します。情報を読み取ることと、その意味を編集機能として実装することは別の検証項目です。
import {readNativeWorkspaces,writeNativeWorkspaces} from './psd-workspaces.ts';
import * as ag from './vendor/psd-codec.mjs';
import {supportedColorModes} from './vendor/psd-codec.mjs';
import instantiate from './vendor/lcms/lcms.js';
import {blankDoc,makeLayer,surface,layerSurface,maskSurface,composite,uid,supportedSize,MAX_LAYERS,type Layer,type StudioDoc,type LayerMask} from './document.ts';計算の
内側へ。
未対応の調整を黙って置き換えない
PSD出力へ対応付けできない調整レイヤーは、プロジェクト形式で保持するよう案内するエラーになります。似た機能に置き換えて完全互換とする処理ではありません。.layerstudio原本を併せて残す理由です。
PSBを選んでもアプリの作業空間制限はなくなりません。読み込みでは16,384px・64MPの範囲を確認し、高精度処理には別の制約があります。形式の最大仕様とアプリの処理範囲を区別します。
両形式で二つのレイヤーが戻った
2026年10月22日、1536×1024のAI原画像からPortrait baseとHidden backup 60を作りました。上の複製は不透明度60%で非表示です。プロジェクト原本を保存し、Save As PSDとSave As PSBを実行して、それぞれOpen PSD / PSBで再読み込みしました。
両方で名前・順序・非表示・不透明度0.6が保持されました。ファイルヘッダーもPSDバージョン1、PSBバージョン2、同じ寸法、8ビットと確認しました。今日の直接検査はPhotoshot→ファイル→Photoshotであり、今日Adobe Photoshopで読み直した結果とは説明しません。
コードを読む。
export function packMetadata(v:any):any{if(v===null||typeof v!=='object')return v;if(ArrayBuffer.isView(v))return {__bytes:bytes64(new Uint8Array(v.buffer,v.byteOffset,v.byteLength)),__type:v.constructor.name};if(v instanceof ArrayBuffer)return {__bytes:bytes64(new Uint8Array(v)),__type:'ArrayBuffer'};if(Array.isArray(v))return v.map(packMetadata);const out:any={};for(const [k,x]of Object.entries(v))if(!['canvas','imageData','rawData','rawCompositeData','children','thumbnail','imageDataRaw'].includes(k))out[k]=packMetadata(x);return out;}
export function unpackMetadata(v:any):any{if(!v||typeof v!=='object')return v;if(v.__bytes){const a=from64(v.__bytes);return v.__type==='ArrayBuffer'?a.buffer:v.__type==='Uint16Array'?new Uint16Array(a.buffer):v.__type==='Float32Array'?new Float32Array(a.buffer):a;}if(Array.isArray(v))return v.map(unpackMetadata);return Object.fromEntries(Object.entries(v).map(([k,x])=>[k,unpackMetadata(x)]));}export function resourceRange(bytes:Uint8Array){const v=new DataView(bytes.buffer,bytes.byteOffset,bytes.byteLength),lengthOffset=30+v.getUint32(26),start=lengthOffset+4,end=start+v.getUint32(lengthOffset);if(end>bytes.length)throw Error('Truncated PSD image resources.');return {lengthOffset,start,end};}
export function resourceBlocks(bytes:Uint8Array){const {start,end}=resourceRange(bytes),v=new DataView(bytes.buffer,bytes.byteOffset,bytes.byteLength),out:{id:number;start:number;end:number;data:Uint8Array}[]=[];let at=start;while(at+12<=end){const first=at,id=v.getUint16(at+4),name=bytes[at+6];at+=6+Math.ceil((name+1)/2)*2;if(at+4>end)throw Error('Invalid PSD resource name.');const length=v.getUint32(at);at+=4;if(at+length>end)throw Error('Invalid PSD resource length.');const data=bytes.subarray(at,at+length);at+=length+(length%2);out.push({id,start:first,end:at,data});}return out;}
export function readResource(bytes:Uint8Array,id:number){return resourceBlocks(bytes).find(b=>b.id===id)?.data;} if(l.adjustment){const mapped=adjustmentOut(l.adjustment,out.adjustment);if(mapped){out.adjustment=l.psdAdjustmentOriginal===JSON.stringify(l.adjustment)?out.adjustment:mapped;out.clipping=l.adjustment.scope==='clipped';}else throw Error('PSD export does not yet support '+l.adjustment.type+' adjustment layers. Save a Photoshot project to preserve them.');}エディターで見る。

試験ファイルと全ファイルを区別する
保存済みprecision-psd-render報告はRGB16・RGB32・CMYK16・Lab16のPSD/PSB八組を通過と記録しています。ファイル日付は2026年10月13日です。今日再実行した検査ではなく、今回の8ビット人物写真の基本レイヤー確認とも別です。
機能対照表には文字スタイル、効果の組合せ、Adobe描画全体との同等性などの未検証範囲が残っています。人物はAI生成、作業画面は実際のキャプチャーです。21回はレイヤーグループ・効果・マスクの文書構造へ続きます。
原画像とPSD再読込。


AI生成の動作例用写真。編集画面と出力画像は実際のPhotoshotで作成しました。