Эффективное составление / рендеринг нескольких слоев для Photoshop-подобного графического редактора - PullRequest
3 голосов
/ 22 февраля 2011

Я делаю Photoshop-подобное приложение, которое имеет 5 или около того слоев 1600x1200.Каждый слой может иметь различные режимы смешивания, такие как нормальное смешивание, смешивание XOR, добавочное смешивание и т. Д., Где обычное смешивание является наиболее распространенным.Смешивание всех слоев вместе занимает около 0,3 с на моей целевой платформе (здесь доступно аппаратное ускорение).

Моя проблема: Как я могу эффективно обновить экран, чтобы показать все слои, сплющенные / смешанные вместе, когдапользователь выполняет операции редактирования на слое?

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

Единственные оптимизации, о которых я могу думать:когда происходят изменения, обновляйте только прямоугольник сглаженного изображения, которое изменилось.Это будет быстро для небольших изображений кисти, например.

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

2 не помогает, если вы редактируете нижний слой, а яне вижу, как я могу предварительно сгладить все слои над активным слоем.

1 Ответ

0 голосов
/ 22 февраля 2011

Не зная вашей целевой платформы, настоятельно рекомендуется какое-то аппаратное ускорение. OpenGL 2.0+ (или ES 2.0+), скорее всего, поможет - используя GLSL, вы получите язык C-стиля, в котором вам будет интересна поставка фрагментированной программы, которую GPU должен делать для каждого пикселя на основе на входных текстурах, чтобы произвести цвет для вывода. То, куда вы выводите, является неявным, но вы можете вывести на изображение, а затем впоследствии использовать это изображение в качестве входных данных, что бы сразу увязалось с вашей идеей (2). В зависимости от конкретного оборудования, на которое вы нацеливаетесь, может быть уместно, что Direct3d имеет очень похожую конструкцию в HLSL, а NVidia предоставляет более проприетарный эквивалент, называемый Cg, который, я думаю, в настоящее время может компилироваться в GLSL или HLSL.

В противном случае: идея (1) - это разумный ход, особенно если пользователю разрешено открывать изображения произвольного размера. Это приводит к тому, что затраченное время зависит от размера кисти, а не от изображения. Вы должны быть достаточно точными в своем мышлении, если вы делаете вещи с точностью до субпикселя.

Идея (2) потенциально имеет прецизионные последствия (особенно если они связаны с оборудованием) Чтобы поддерживать те же самые результаты, очевидно, что ваши промежуточные буферы должны быть с той же точностью, что и ваши промежуточные переменные, что в типичном ориентированном на потребителя приложении для рисования часто означает, что входные данные для файлов имеют размер 8 бит на канал / канал, но промежуточное хранилище должно быть не менее 16 бит на дюйм / канал, если вы не хотите, чтобы ошибки накапливались. Это, вероятно, будет самым большим потенциальным барьером для аппаратного ускорения, так как старое оборудование имеет тенденцию ограничивать вас промежуточными буферами 8bpp / channel. Современное оборудование может создавать буферы с плавающей запятой приличной точности.

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

В общем случае, при обычном смешивании, применяемом ко всем слоям, вы в конечном итоге получите одну операцию для произвольного числа слоев выше.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...