2009-04-04 9 views
7

この問題は一般的に描画システムに当てはまります。私は、元に戻す機能がPSでどのように実装されているのだろうかと思いました。各操作の前にキャンバスのスナップショットを作成しますか?もしそうなら、これは膨大なメモリ要件につながりませんか?私はCommandパターンを調べましたが、これが描画にどのように適用されるのかはよく分かりません。Photoshop Undo System

よろしく、 メノ

+0

なぜ閉じるのですか?これは駄目か何か?閉鎖の後にコメント –

+0

があるはずです[このSOのスレッド](http://stackoverflow.com/questions/3541383/undo-redo-implementation/3542670#3542670)を見てください。 – Lazer

答えて

12

それはcommand patternと呼ばれています。どんなエディタにも便利なように実装するのは簡単です。

Photoshopは、元の画像に積み重なった変形を適用します。 1つのopetation 1コマンド。元に戻すと、変換の適用が解除されます。だから、元のバージョンと最新のバージョンを保持しているだけですが、パフォーマンスのために最後のいくつかのバージョンをキャッシュするかもしれないと思います。

+0

私はこれをWYSIWYGエディタで実装しました。最初は不可能だったようですが、いったんパターンを把握すれば、それはかなり簡単です。 –

+0

それは私の同じ経験ですが、私はそれは決してうまくいかないと思っていました。秘密がなければいけませんでしたが、一度完成すればうまくいっています:) –

+0

実際、現在のバージョンは現在のバージョンだけです。逆のコマンドのリスト少なくともそれはワープロがそれをする方法です。 – jmucchiello

4

いくつかの操作は不可逆的なので、イメージ全体がスナップショットされるたびに疑問から外れると思いますが、デルタのスタックだけが表示されます。デルタは、操作の前に修正されたピクセルを含むマスクのセットである。もちろん、多くの操作はリバーサルにできるので、デルタを最適化することができます。

+0

また、Photoshopは、アンドゥ情報のためにハードディスクを使用するため、そこに追加のメモリが必要ありません。 – Joey

-2

Photoshopは履歴を使用してアクションを追跡します。これらは、元に戻すことができるので、いつでも元に戻すことができます。設定で履歴のサイズを設定できます。

Adob​​e Version Cueは、逆戻りの元に戻すツールやバージョンとして、この唯一の目的でスイートに組み込まれています。 http://en.wikipedia.org/wiki/Adobe_Version_Cue

+0

この質問は実装の詳細です。 – tmcw

4

私は、Adobe Photoshopはundoを実装する方法わからないんだけど、Apple Shake合成アプリケーション内のペイントノードを説明するのはとても簡単です:

  • 各ストロークは、いくつかの情報と共に、一連の点として保存されていますストロークカラー、ブラシサイズなどのようなものです。
  • ストロークを描くと、現在の画像に変更が加えられます。
  • すべてのxストローク(私は思う)現在のイメージはメモリにキャッシュされます。
  • 元に戻すと、前のキャッシュされたイメージの最後の〜9ストークが再描画されます。

    • あなたは10倍以上を元に戻すときは、それは全体の画像を再計算する必要があります:

    は、この2つの問題があります。数千回のストロークで数秒間休止することがあります。

  • Shakeでは、実際のピクセル値ではなく、ストローク情報を含む設定ファイルを保存します。つまり、ペイントノードを再び開くか、イメージをレンダするたびにイメージ全体を再計算する必要があります(ただし、元に戻すことと同じくらい大きな問題ではありません)。

さて、シェイクはひどくバグであり、多くの分野で実装されていないという点が第3の問題です。ペイントノードはその1つではありません。実装がどれくらい良いか分かりませんが、 Photoshopがあまりにも異なると想像することはできません(遠く)。

enter image description here

あなたが考える:

0

私はアドビシステムズ社がそれに取り組む方法を私は知りませんが、この問題を解決するために見つけた最も簡単な方法は、そのように、永続的なデータ構造を使用することです画像タイルの集合としての画像、例えばそれぞれ64x64ピクセルで、ガベージコレクションや参照カウントを取得します(例:C++でshared_ptrを使用)。これらの暗いタイルは、このような変化にコピーされた浅い以外

enter image description here

すべて:

は今、ユーザーが画像タイルへの変更を行う際には、新しいバージョンの浅いコピー中に変更されていないタイルを作成します。あなたがそのように行う際に、あなたの全体のアンドゥシステムはこれに沸く:

before user operation: 
    store current image in undo stack 
on undo/redo: 
    swap image at top of undo stack with current image 

そして、それは、それぞれに何度も保存されるように画像全体を必要とせずにそのように超簡単になったエントリを元に戻します。ユーザーがレイヤーをコピー&ペーストするときのボーナスとして、ペーストされたレイヤーを変更しない限り、それ以上のメモリはほとんど必要ありません。それは基本的にイメージのインスタンス化システムを提供します。さらに別のボーナスとして、ユーザーが2000x2000ピクセルの透明レイヤーを作成した場合、100x100ピクセルのようなわずかなイメージしか描画しないため、空の透明タイルは任意のピクセルを格納しなければならず、ヌルポインタの数が2つしかありません。また、空の画像タイルをアルファブレンドする必要がなく、スキップするだけで済むため、ほとんど透明なレイヤーで合成を高速化できます。同様に、空のタイルをスキップすることもできるので、画像フィルタのスピードも上がります。

PSアクションに関しては、これは少し異なるアプローチです。いくつかのスクリプトを使用して、実行するアクションを指定することもできますが、上記のものと組み合わせて、変更された部分だけを効率的にキャッシュすることができます。このアプローチの全体的なポイントは、イメージの全体を何度も完全にコピーしなくてはならないことと、すべての種類の個別の元に戻す/やり直しロジックを書き込むことなく元に戻すために、発生する可能性のある異なる操作。