2017-04-04 18 views
2

明らかに変更の履歴の配列を格納するために多くのメモリを取る...それは私が働いて自分のアプリケーションを持っていた方法ですが、これを行うことについて移動するよりスマートな方法がありますようにそれはちょうどそうです。写真編集アプリケーションで「元に戻す」機能を実装する最善の方法は何ですか?

ArrayList<Photo> photoHistory = new ArrayList<>(); 
photoHistory.add(originalPhoto); 
photoHistory.add(change1); 
photoHistory.add(change2); 

// bad implementation - lots of memory 

オリジナルのビューモデルと現在のビューモデルのみを保存し、使用するメソッド/フィルタのログを保持することはありますか?ユーザーが「元に戻す」とヒットした場合、変更の総数がもう一度マイナス1になります。これはまた非常に非効率的なようです。

私はちょうどソフトウェア・アプリケーションの機能を「元に戻す」一般を実装する方法についてアドバイスを探していますね。ここで

+2

https://en.wikipedia.org/wiki/Command_pattern –

+0

変更を逆に新しいバージョンに適用するには、後と変更前の間、すなわちデルタデルタを計算します。歴史はその三角です。完全なフィルタの場合、完全な画像になる可能性がありますが、赤目フィルタのようなものは、目だけです。つまり、はるかに小さくなります。 – Andreas

+0

まあ、@AndyTurnerによってリンクコマンドパターンは、あなただけの一般的な元に戻す機能を持つようにしたい場合は、一般的にフォローする微細なパターンです。しかし、グラフィックアプリケーションのシナリオでは非常に複雑になるのは、(すべてのコマンドに追加する必要がある)元に戻すメソッド自体です。コマンドで取り消しを実装するのは簡単ではないかもしれません。あなたが言及したように、実行されたコマンドのリストを保持し、最後のコマンドを元に戻すときに前のコマンドを再適用することができます。それでも、これは非常に非効率的なことがあります。一般的なシナリオでは、コマンドパターンは大丈夫ですが、グラフィカルエディタでは最適なオプションではないかもしれません。 –

答えて

2

はGIMPがそれを実装する方法のヒントです:

元に戻すのGIMPの実装はかなり洗練されています。多くの操作は、(例えば、レイヤーの可視性を変更すること)はほとんど元に戻すメモリを必要とするので、彼らは取り消し履歴からドロップアウトする前に、あなたはそれらの長いシーケンスを実行することができます。レイヤーの可視性を変更するなどのいくつかの操作は圧縮されているため、それらを複数回連続して実行すると、元に戻す履歴には1つのポイントしか作成されません。ただし、多くのUNDOメモリーを消費する可能性のある操作があります。ほとんどのフィルタはプラグインで実装されているため、GIMPコアには何が変更されたかを知る効率的な方法がありません。このように、操作の前後に影響を受けたレイヤーの内容全体を記憶すること以外は、取り消しを実装する方法はありません。これらの操作は、元に戻すヒストリーから抜ける前に実行することができます。

Source

だから、できるだけ最適にそれを行うために、あなたは取り消されているもののアクションに応じて、さまざまなことを行う必要があります。レイヤーを表示または非表示にすることはスペースの無視できる量で表現することができますが、画像全体をフィルタリングして画像全体の別のコピーを保存する必要があります。ただし、画像の一部のみをフィルタリングするか(または画像の小さな部分に描画する)場合は、その画像を保存する必要があります。

関連する問題