1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

DelphiでPSDファイルを読み込んでプレビュー表示する

Last updated at Posted at 2025-11-05

🖋 はじめに

Delphiで Photoshop の .psd ファイルを直接読み込み、
レイヤーツリーと画像プレビューを表示できる PSDビューワ のサンプルを公開しました。

内部の合成処理には自作クラス TPSDImage を使用しており、
PSDToolKit 互換構造を持つため、レイヤー単位の操作にも対応しています。

修正バージョンでは、非表示レイヤーを後読み(オンデマンド読込)方式 に変更し、
200MB級の大容量PSDでも高速にプレビューできるよう最適化しました。


📂 サンプルプロジェクトの構成

ファイル 内容
PSDImageForm.pas メインフォーム(UI部分、処理時間計測付き)
PsdFileImageFrame.pas PSDプレビュー表示用フレーム(市松模様背景対応)
PsdFileTreeFrame.pas レイヤーツリー表示用フレーム
PSDImage.pas PSDファイル読込・合成クラス(後読込対応)

💡 主な変更点(前回公開版との違い)

項目 説明
読込方式 全レイヤー一括 → 非表示レイヤーは後読込(Lazy Load) に変更
メモリ効率 表示中のレイヤーのみ展開、他はオフセット情報のみ保持
ファイルアクセス 表示切替時に必要レイヤーのみ再オープンしてデコード
安定性 ファイルを開きっぱなしにせず、必要時のみアクセス
表示 市松模様背景で透過プレビューを実現
αブレンド VCL制約内で擬似的に再現し、PNG保存時は透明保持

🧩 クラス構成

🟦 TPSDImage

PSDの全体情報を管理するクラス。
レイヤー構造・リソース・オフセット情報を保持し、
必要時のみピクセルデータを再読込します。

主な処理:

procedure LoadFromFile(const FileName : string);
procedure Render;
procedure UpdateVisibleLayers;

仕様:

  • 初回読込ではレイヤーメタ情報(位置・サイズ・可視状態・オフセット)のみ解析
  • 非表示レイヤーはファイルを開かずにスキップ
  • 表示切替時に UpdateVisibleLayers が必要分を読み込み
  • 透明を保持したまま TBitmap として利用可能

🟩 TFramePsdFileImage

PSDプレビューを行うフレーム。
背景には市松模様を描画し、透明部分の視認性を確保。

procedure TFramePsdFileImage.OnDrawFinish(Sender: TObject);
begin
  DrawCheckerBoard(Canvas, r, 16);
  RectToStreachRect(r, FPsdImage.Bitmap.Width, FPsdImage.Bitmap.Height);
  ImagePsd.Canvas.StretchDraw(r, FPsdImage.Bitmap);
end;
  • GDIでは透明合成不可のため、見た目上で擬似的に透過再現
  • TPngImage.Assign(Bitmap) で保存時は完全な透明を維持可能

🟨 TFramePsdFileTree

PSDのレイヤー階層(フォルダ構造)を TTreeView で表示。
クリックイベントで該当レイヤーの表示状態を切り替え、
必要であれば再読込が行われます。

procedure TFormPSDImage.OnTreeClick(Sender: TObject);
begin
  FPSDImage.UpdateVisibleLayers;
  FFrameImage.ShowImage;
end;

🖼 メインフォームの構成

procedure TFormPSDImage.Button1Click(Sender: TObject);
begin
  OpenDialog1.Filter := 'PSD files (*.psd)|*.psd';
  if not OpenDialog1.Execute then Exit;

  StartTimer('Load');
  FPSDImage.LoadFromFile(OpenDialog1.FileName);
  StopTimer('Load');

  StartTimer('Tree');
  FFrameTree.ShowTree;
  StopTimer('Tree');

  StartTimer('View');
  FFrameImage.ShowImage;
  StopTimer('View');

  Caption := Format('PSD表示テスト - %s', [ExtractFileName(OpenDialog1.FileName)]);
end;

StartTimer / StopTimer はグローバル関数として定義され、
デバッグ出力(OutputDebugString)に処理時間を自動表示します。
これによりロード・ツリー構築・描画それぞれのパフォーマンスを簡単に計測可能です。


🚀 後読込方式(Lazy Load)の効果

巨大なPSDを扱う際の処理効率が劇的に改善されます。

処理項目 旧方式(全読込) 新方式(後読込)
初回読込時間 数秒〜数十秒 数ms〜100ms前後
メモリ使用量 数百MB 数十MB以下
表示切替 即時反映 非表示→表示で必要分のみ再読込
ファイルハンドル 常時オープン 必要時のみオープン/クローズ

🧾 出力結果

  • 透明部分も保持された状態でプレビュー表示
  • PNG保存 (TPngImage.Assign(FPSDImage.Bitmap)) により透明画像をそのまま出力可能
  • デバッグ実行時には各処理時間がログに出力され、パフォーマンス検証が容易

⚙️ 動作環境

  • Delphi 11 / 12
  • Windows 10 / 11
  • 依存ライブラリ:なし(VCLのみで動作)

📘 まとめ

  • PSDのレイヤー構造を解析・プレビュー表示
  • 非表示レイヤーはファイルを閉じたまま後読み対応
  • 巨大PSDでも軽快な動作を実現
  • デバッグログで処理時間の可視化が可能
  • PNG出力では透明を保持

PSDファイルを扱うための 軽量・高速な最小構成サンプル として利用できます。


📄 ライセンス

MIT License


📦 GitHubリポジトリ
https://github.com/vramwiz/PsdImage

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?