2017-04-04 72 views
2

很明顯,它需要大量的內存來存儲更改歷史數組......這就是我如何讓我的應用程序工作,但似乎有一個更聰明的方法來做到這一點。在照片編輯應用程序中實現「撤消」功能的最佳方式是什麼?

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

// bad implementation - lots of memory 

也許只存儲原始視圖模型和當前視圖模型,並保存使用的方法/過濾器的日誌?那麼,當用戶點擊「撤消」時,它會將所做的更改總數再次減去一個?這似乎也非常低效。

我想我只是在尋找關於如何實現一個軟件應用程序的一般'撤銷'功能的建議。

+2

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

+0

計算變更之前和之後的增量,即應用於新版本以反轉變化的增量。歷史就是那些三角洲。對於完整的濾鏡,可能是完整的圖片,但對於紅眼濾鏡之類的東西,它只是眼睛,即小得多。 – Andreas

+0

那麼,通過@AndyTurner鏈接的命令模式是一個很好的模式,如果你只是想擁有一個通用的撤銷功能,那麼這個模式通常會遵循。但是,在圖形應用程序場景中,它的複雜性在於撤消方法本身(需要將其添加到每個命令中)。在命令中實現撤消可能並不那麼容易。正如你所提到的那樣 - 你可以保存已執行命令的列表,並在撤銷最後一個命令時重新應用以前的命令。不過,這可能效率很低。因此,總結一下 - 在一般情況下,命令模式可以,但可能不是圖形編輯器中的最佳選項。 –

回答

2

這裏是GIMP如何實現它的提示:

GIMP的實施撤消是相當複雜的。許多操作只需要很少的撤消內存(例如,改變圖層的可見性),因此您可以在退出撤消歷史記錄之前執行很長的一系列操作。某些操作(例如更改圖層可見性)會被壓縮,因此連續多次執行操作會在撤消歷史記錄中只生成一個點。但是,還有其他操作可能會消耗大量的撤消內存。大多數過濾器都是通過插件實現的,所以GIMP內核沒有有效的方式來知道發生了什麼變化。因此,除了通過在操作之前和之後記憶受影響層的全部內容,無法實現撤消。您可能只能在退出撤消歷史記錄之前執行一些此類操作。

Source

因此,要做到這一點儘可能優化,你必須做取決於什麼動作而復不同的事情。顯示或隱藏圖層可能會佔用很小的空間,但過濾整個圖像可能需要存儲整個圖像的另一個副本。但是,如果您只過濾圖像的一部分(或在圖像的一小部分中繪製),則可能只需要存儲該圖像的一部分。

相關問題