2009-04-04 3 views
7

Вопрос, вероятно, относится к системам рисования в целом. Мне было интересно, как функция отмены отменена в PS. Выполняет ли программа снимки холста перед каждой операцией? Если это так, не приведет ли это к огромным требованиям к памяти? Я просмотрел шаблон Command, но я не могу понять, как это применимо к чертежу.Система Photoshop Undo

С уважением, Менно

+0

Зачем закрывать? Это обман или что-то еще? За закрытием должны следовать комментарии –

+0

Посмотрите на [эту SO-нить] (http://stackoverflow.com/questions/3541383/undo-redo-implementation/3542670#3542670). – Lazer

ответ

12

Это называется command pattern. Его просто реализовать как полезный для любого вида редактора.

Photoshop применяет складывающиеся преобразования на исходное изображение. Одна команда одной команды. Это просто отменяет преобразование, когда вы отменяете. Поэтому он просто сохраняет оригинальные и новейшие версии, но я думаю, что он может кэшировать последние несколько версий только для производительности.

+0

Я реализовал это в редакторе WYSIWYG. Сначала это кажется невозможным, но как только вы поймете шаблон, это очень легко. –

+0

Это мой опыт, я думал, что это никогда не сработает, и что там должен быть секретный ингридиент, но как только я закончил, он просто сработал :) –

+0

На самом деле, текущая версия - это только существующая версия, и история команд на самом деле список отмененных команд. По крайней мере, так будет работать текстовый процессор. – jmucchiello

4

Поскольку некоторые операции будут невосстанавливаемыми, и, как вы говорите, моментальный снимок всего изображения каждый раз будет не вдаваться в вопрос, тогда единственная альтернатива, которую я вижу, - это стек дельт. Дельта - это набор масок, содержащих модифицированные пиксели до операции. Конечно, многие операции могут быть обратимыми, поэтому их дельта можно оптимизировать.

+0

Также Photoshop использует жесткий диск для отмены информации, поэтому никаких дополнительных требований к памяти нет. – Joey

-2

Для этого необходимо использовать History. Они также служат как Отменить, поскольку вы можете вернуться в историю в любой момент. Вы можете установить размер истории в настройках.

Я также предлагаю вам ознакомиться с Adobe Version Cue как инструмент для ретроспективного отскока или версий, он встроен в набор для этой единственной цели. http://en.wikipedia.org/wiki/Adobe_Version_Cue

+0

Этот вопрос касается деталей реализации. – tmcw

4

Я не уверен, как Adobe Photoshop реализует undo, но узел Paint в Apple Shake композитинга приложения довольно легко объяснить:

  • Каждый топить хранится в виде последовательности точек, наряду с некоторой информацией как цвет штриха, размер кисти и т. д.
  • Когда вы рисуете сток, изменения производятся на текущем изображении.
  • Каждые x штрихи (10, я думаю) текущее изображение кэшируется в память.
  • Когда вы отменяете, он перерисовывает последние ~ 9 стоков на предыдущем кэшированном изображении.

Есть две проблемы:

  • При отмене более чем в 10 раз, он должен пересчитать все изображение. С тысячами ударов это может вызвать несколько секунд паузы.
  • С помощью Shake вы сохраняете файл установки, содержащий информацию о штрихе, а не фактические значения пикселей. Затем вы должны пересчитать все изображение всякий раз, когда вы снова открываете узел Paint, или визуализируете изображение (но не настолько большую проблему, как вещь отмены).

Ну, есть третья проблема: если Shake ужасно глючит и плохо реализуется во многих областях, узел Paint выделяет один из них - поэтому я не уверен, насколько хороша реализация, но я не может представить, что Photoshop слишком разнороден (хотя далеко лучше оптимизирован).

0

Самый простой способ я нашел, чтобы решить эту проблему, хотя я не знаю, как Adobe решает его, чтобы использовать постоянную структуру данных, например, так:

enter image description here

Вы думаете о изображение как набор графических фрагментов, скажем, 64x64 пикселей каждый, и они получают собранный мусор или подсчет ссылок (например: используя shared_ptr в C++).

Теперь, когда пользователь вносит изменения в фоновое изображении, вы создаете новую версию, пока неглубокое копирование немодифицированных плиток:

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 

И становится очень легко, как, что, не требуя полное изображение будет храниться снова и снова в каждом отменить запись. В качестве бонуса, когда пользователи копируют и вставляют слои, он едва занимает больше памяти, если/до тех пор, пока они не вносят изменения в этот вставленный слой. Он в основном предоставляет вам систему instancing для изображений. Еще один бонус, когда пользователь создает прозрачный слой, скажем, 2000x2000 пикселей, но они только рисуют немного изображения, например, говорят только 100x100 пикселей, что также едва ли берет память, потому что пустые/прозрачные плитки не должны хранить любые пиксели, только пару нулевых указателей. Он также ускоряет компоновку с такими прозрачными слоями, потому что вам не нужно альфа-смешивать пустые фрагменты изображений и просто пропустить их. Он также ускоряет фильтрацию изображений в тех случаях, так как они также могут просто пропускать пустые плитки.

Что касается действий PS, это немного другой подход. Там вы можете использовать некоторые скрипты, чтобы указать, какие действия выполнять, но вы можете связать их с приведенным выше, чтобы эффективно кэшировать только измененные части изображения. Весь смысл этого подхода состоит в том, чтобы избежать необходимости глубокой копии всего изображения снова и снова и взорвать использование памяти для кэширования предыдущих состояний изображения для отмены, не прибегая к написанию отдельной логики отмены/повтора для всех видов различные операции, которые могут произойти.