Список вопросов
Как зайти в Даркнет?!
25th January, 01:11
8
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
900
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
952
0
Очень долго работает Update запрос Oracle
27th January, 09:58
916
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
907
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
942
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1727
0
период по дням
25th October, 10:44
3957
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3722
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4614
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4382
0
Помогите пожалуйста решить задачи
24th November, 23:53
6088
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4352
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4400
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Сохранение истории в графическом редакторе?
Просмотров: 373
 
Ответов: 4
Здравствуйте. Вот задался вопросом — как корректно сохранять историю в графическом редакторе (как Гимп) для использования в UNDO/REDO. Сам вижу три варианта:
1. Сохранять список действий.
Например, нарисовал линию такого-то цвета в таких координатах, применил фильтр «Блур», повернул изображение. В случае использования UNDO проходятся все действия от первого до необходимого.
Преимущество: Занимает очень мало места в памяти. При сохранении проекта можно с легкостью восстановить всю историю. При желании можно даже хранить полное дерево (например сделали действие A, B, C, D, E, вернулись к С, сделали F, G. Итоговый путь получился ABCFG, но можно как в системе контроля версий сохранить и ветку DE)
Недостаток: При использовании Undo или загрузке ранее сохраненного изображения проходится весь путь, а это может играть существенное время и если при обычном простом редактировании такой проход может занять каких-то 100-200 мс, что некритично, так при использовании тяжелых фильтров может замедлиться до десятков секунд.
2. Сохранять полный дамп проекта в bitmap
Каждое действие всю картинку мы сохраняем в память как готовый рисунок.
Преимущество: Очень быстро работает. Сделали undo/redo и просто показали из памяти тот рисунок, который у нас был (уже отрендеренный). Даже тяжелый фильтр, что угодно.
Недостаток: Занимает очень много места в памяти. Допустим, у нас рисунок размером 1k*1k. В каждом пикселе мы храним 32 бита информации (по 8 бит на r,g,b и 8 бит на альфаканал), то есть 4 байта, то есть такой битмап у нас будет занимать в идеале 4 метра, а история из 64 действий — 64*4 = 256 мб в памяти. А если допустить, что у нас графический редактор поддерживает слои и пусть их будет хотя бы пять… Аналогично, проекты с историей хранить тяжело.
Gimp
В Гимпе по косвенным признакам я опеределил, что используется второй подход. Признаки такие:
1. История ограничена
2. Тяжелые фильтры при ундо-редо возвращают статус кво очень быстро.
3. Совмещенный подход
Конечно, есть альтернатива. Храним историю первым способом, а последних, например, 8 действий храним вторым способом, т.к. редко используется такой дальний undo. Сохранять на винт можно только действия, из-за чего проект с множеством изменений будет долго открываться, но допустимо весить. Или еще добавить последнюю битмап дату.
Преимущества обоих подходов
Недостаток — значительно утяжеляется логика приложения. Фактически — надо реализовывать два механизма истории.
Тема для обсуждения
Что скажете вы? Может, есть еще какой-то подход. Если нет, то какой из подходов предпочли бы вы (в идеальном случае и в случае очень сжатых сроков)? Почему?
По моему третий способ было бы логично дополнить некими ключевыми кадрами (по аналогии с видео), по сути bitmap, которые бы сохранялись после тяжелых фильтров и хранились бы не в оперативе, а на винте (во временной папке). Т.е. как Вы и описали, несколько последних действий в оперативке в виде bitmap. История назад в виде списка действий от ключевых кадров (тяжелых фильтров). Да и такие ключевые кадры было бы логично хранить не в сыром виде, а хоть в том же png. Это позволит не так значительно тормозить при откате на далекую историю и экономить место на винте за счет сжатия png.
А вообще, идею с ключевыми кадрами можно было бы вообще полностью применить вместо третьего варианта. Т.е. мелкие действия хранить именно как действия, а более тяжелые, как ключевые кадры в виде bitmap в оперативке. Если более тяжелое действие отодвигается в прошлое, то паковать его в png и сбрасывать на винт.
И… по поводу слоёв… у нас же undo обычно применяется к конкретному действию на конкретном слое, а не ко всем слоям одновременно. Конечно есть live-фильтры, но это отдельная история. Я к тому, что число слоёв не увеличивает кол-во bitmap пропорционально.
А нельзя в каких-то случаях выстроить последовательность, обратную первой?
В смысле, бывают обратимые изменения, а бывают необратимые. Логично хранить ключевой кадр после необратимых, а от основного состояния достраиваться до ближайшего обратимого в обратном порядке, используя историю на уже имеющийся кадр, проходя путь с конца, а не с начала.
Чтобы ответить на вопрос вам нужно войти в систему или зарегистрироваться