AI生成の動作例用写真 / 編集前
DEVELOPMENT JOURNAL / 08
Photoshot
GITHUB × AI
無料Photoshop代替の開発記

カラーバランスの計算

明暗の領域ごとに色を調整する機能は、既存のエディターにもありました。必要だったのは動作を理解し、蓄積した調整エンジンに実装することです。GIMPの文書、再利用するPhotoshotのコード、AIと書いて修正した計算を組み合わせました。

PHOTOSHOT DEVELOPMENT JOURNAL / 08

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

Photoshot無料Photoshop代替の開発記 / 08FOUNDATION

ソースから始める。

既知の設計と再利用できるエンジン

GIMPの文書は、どんな操作を提供するかを確認する基盤でした。Photoshotには入力・保存・合成のコードがすでにあったため、新しい作業を明暗別の計算とオプションの接続に集中できました。AIはその実装と後続の修正に使いました。

9月18日の元セッションにはGIMPのColor Balance文書を開いた記録があります。3つの階調範囲と輝度を維持するオプションの構成を確認しました。文書の参照は、GIMPの計算コードを導入したという意味ではありません。

ポトショットでは各範囲のR・G・B設定を保存し、共通の調整レイヤーで処理します。以下は公開版v0.16.0の自作コードです。以前の式も同じファイルに残り、変更をたどれます。

最初は3つの重みを混ぜた

初期計算ではRGBの最大値と最小値の平均をlとしました。重みは暗部が(1−l)²、明部がl²、中間調が2l(1−l)です。合計は1で、l=0.5なら0.25・0.5・0.25になります。

中間調は明確に区切った区間ではなく、他の範囲と重なる影響でした。3つの設定を重みで混ぜて各チャンネルに加えます。初期実装を説明しやすい式ですが、後のすべての処理をこの式だけで説明することはできません。

初期計算は文書構造を置き換えずに接続できました。共通エンジンが値の保存と合成を担い、カラーバランスは色の変化に集中します。役割を分けたコードをAIと拡張することで、同じ実装の繰り返しを減らせます。

src/adjustments.ts · v0.16.0
L650–663
Photoshotの実装コード ↗
if (t === 'balance' && a.revision !== 2) {
  const l = (Math.max(r, g, b) + Math.min(r, g, b)) / 2,
    sh = (1 - l) ** 2,
    hi = l * l,
    mid = 2 * l * (1 - l);
  for (let c = 0; c < 3; c++)
    out[c] = clamp(
      out[c] +
        (v['shadows' + 'RGB'[c]] * sh +
          v['midtones' + 'RGB'[c]] * mid +
          v['highlights' + 'RGB'[c]] * hi) /
          100,
    );
  if (v.preserve) preserveLuma(out, luma(r, g, b));
Photoshot無料Photoshop代替の開発記 / 08IMPLEMENTATION

計算の
内側へ。

輝度維持を有効にした新しい計算

revision 2で輝度維持を有効にすると、チャンネルごとにblack・white・gammaを作ります。暗部設定を黒側の基準、明部設定を白側の基準、中間調設定をガンマへ接続し、入力範囲の正規化とガンマ処理を行います。

「輝度維持」は製品のオプション名です。すべての画素で特定の輝度式が数学的に完全保存される保証へ広げてはいません。実際のコードを示すことで、この違いを説明できます。

維持をオフにすると応答表を順に適用する

同じrevision 2でも維持をオフにするとbalance-response.tsの応答表を使います。zoneは2から0へ減るので、ハイライト、中間調、シャドウの順です。前の計算結果を次へ渡します。

初期版のように3つの重み付き変化を一度に加える構造ではありません。revision分岐により、以前のプロジェクトは従来の計算を保ち、新しい調整は改善後の経路を選べます。

PHOTOSHOT / SOURCE NOTES08

コードを読む。

src/adjustments.ts · v0.16.0
L674–679
Photoshotの実装コード ↗
  const key = 'RGB'[c],
    black = shMax - v['shadows' + key],
    white = 255 - v['highlights' + key] + hiMin,
    gamma = 2 ** ((v['midtones' + key] - midCenter) / 100);
  out[c] = clamp((out[c] * 255 - black) / Math.max(1, white - black)) ** (1 / gamma);
}
src/adjustments.ts · v0.16.0
L683–689
Photoshotの実装コード ↗
for (let zone = 2; zone >= 0; zone--)
  out[c] = sampleResponse(
    balanceResponse[zone],
    v[['shadows', 'midtones', 'highlights'][zone] + key],
    -100,
    out[c],
  );
Photoshot無料Photoshop代替の開発記 / 08IN PRACTICE

エディターで見る。

実際のPhotoshot作業画面。設定と写真を一緒に確認できます。
実際のPhotoshot作業画面。設定と写真を一緒に確認できます。

写真例の設定と次の作業

保存済みの例は中間調のRed+12、Blue−10、輝度維持オンです。Greenと他の階調設定は0です。AI生成写真をポトショットで編集した実例であり、3範囲の全組み合わせを検証した証拠ではありません。

この回が示すのは外部ソースの直接移植ではなく、既知の機能設計と共通コードの再利用です。AIの貢献には公開コードを読む支援だけでなく、既存の基盤に不足する計算とオプションを実装してつなぐ作業も含まれます。

再利用したのは調整レイヤーの入力・保存・合成の流れで、変更したのは内部の色計算です。次回の白黒では、色を消した後も元の赤や青の明るさを別々に調整します。

Photoshot無料Photoshop代替の開発記 / 08BEFORE / AFTER

写真で見る結果。

AI生成の動作例用写真 / 編集前
01 / AI生成の動作例用写真 / 編集前
Photoshotの出力 / 編集結果
02 / Photoshotの出力 / 編集結果

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