Справочник функций

Ваш аккаунт

Войти через: 
Забыли пароль?
Регистрация
Информацию о новых материалах можно получать и без регистрации:

Последние темы форума

Показать новые сообщения »
реклама
Самое сложное не быть середняком дизайн бюро http://www.brand-expert.ru/.

Почтовая рассылка

Подписчиков: 11896
Последний выпуск: 19.06.2015

Написание плагинов для Adobe Photoshop

Автор: Вежневец Владимир
vvp@graphics.cs.msu.su
http://cgm.graphicon.ru:8080/issue3/photoshop/

Содержание

  1. Введение
  2. Общая архитектура plug-in модулей
  3. Функции обратного вызова (callback-функции)
  4. Работа с памятью
  5. Порядок взаимодействия редактора и фильтрационного плагина
    1. Подготовка к работе
    2. Фильтрация изображения
    3. Завершение работы
  6. Важные поля структуры, передающийся через pluginParam
  7. Оформление ресурсов плагина
    1. Ресурсы 'PiMI'
    2. Ресурсы 'PiPL'
  8. Заключение
  9. Список литературы

1  Введение

Встраиваемые модули (plug-in modules, далее плагины) популярного графического редактора Adobe Photoshop являются отдельными программными библиотеками, расширяющими стандартную функциональность редактора. Добавление новых и модификация имеющихся плагинов не требует внесения изменений в сам редактор, что позволяет гибко наращивать его функциональность. В данной статье кратко рассказывается о архитектуре фильтрационных плагинов и порядке их взаимодействия с редактором. Целью статьи является не заменить документацию [1, 2], прилагаемую к Adobe Photoshop SDK (комплекту программных средств, документации и исходных кодов, позволяющий создавать собственные плагины), а дополнить ее кратким ознакомительным текстом, для облегчения знакомства с архитектурой фильтрационных плагинов.

Программа, загружающая плагины и вызывающая (использующая) реализованные в них фукнциональности назвается plug-in host (в терминологии Photoshop SDK). Строго говоря, plug-in host'ом может быть не только Adobe Photoshop, его плагины могут использовать и некоторые другие программы, поддерживающие функциональность plug-in host'а. Например Adobe After Effects, Adobe Premiere, Adobe Illustrator, Adobe PageMaker и Adobe PhotoDeluxe, а также некторые другие графические редакторы к Adobe отношения не имеющие. Для краткости далее в статье plug-in host будет называться редактором.

В Adobe Photoshop существую несколько типов плагинов: Automation, Color Picker, Import, Export, Extension, Filter, Format, Parser и Selection. Все эти типы подробно описаны в соотвествующих разделах Adobe Photoshop API Guide, прилагаемом к SDK. Мы рассмотрим тип Filter (фильтрационные плагины), модули этого типа чаще других создаются сторонними по отношению к Adobe разрботчиками. Целью фильтрационных плагинов является обработка и изменение выбранного участка изображения. Все фильтрационные плагины доступны через меню Filter редактора.

2  Общая архитектура plug-in модулей

Плагин Adobe Photoshop в операционной системе Windows представляет собой динамически подсоединяемую библиотеку (dll), с определенным расширением (для фильтрационных плагинов это .8bf), со специальным образом заданными ресурсами и определенной функцией - точкой входа. В ресурсах dll плагина прописывается множество важной информации - начиная от сигнатур, по которым Photoshop "принимает плагин за своего" и заканчивая указанием поддерживаемых плагином режимов изображения (image modes). Подробнее о ресурсах плагина подробнее рассказано в разделе 7.

Прототип функции - точки входа в плагин задается следующим образом:

void ENTRYPOINT (short selector, 
                 void* pluginParam, 
                 long* pluginData, 
                 short* result);

Фактически, это единственная функция, посредством которой редактор "общается" с плагинами. Общение в обратную сторону осуществляется с помощью так называемых функций обратного вызова (callback-функций) - об этом подробнее в разделе . Параметры функции ENTRYPOINT имеют следующую семантику:

  • Параметр selector указывает какое действие плагина редактор хочет инициировать вызовом ENTRYPOINT. На самом деле, все взаимодействие редактора с плагином организовано как последовательность вызовов функции ENTRYPOINT с различными значениями параметра selector. Схема этого взаимодействия для фильтрационных плагинов и возможные значения selector указаны в секции . Общим для всех плагинов является вызов с selector = 0, что означает запрос на вывод About диалога плагина. Смысл других значений этого параметра меняется в зависимости от типа плагина.
  • Параметр pluginParam содержит указатель на структуру, использующуюся для обменом информацией между плагином и редактором. Поля этой структуры описаны подробно в документации, прилагаемой к SDK. Краткое описание некоторых полей pluginParam для фильтрационных плагинов дано в секции . В случае вызова с selector = 0 вместо этой струкутры передается структура AboutRecord (см. документацию к Photoshop SDK [1]).
  • Параметр pluginData содержит указатель на 32-х битное целое число, сохраняемое редактором неизменным между последовательными вызовами плагина. Обычно, это поле используется для хранения дескриптора (handle) блока данных в памяти, который плагин выделяет и использует для собственных нужд. Во время первого вызова процедуры ENTRYPOINT pluginData указывает на нулевое значение (не равен нулю, а именно указывает на целое число, равное нулю).
  • Параметр result указывает на 16-битное целое, через которое плагин сообщает редактору о статусе завершения инициированной редактором операции. Значение result должно выставляться при каждом вызове функции ENTRYPOINT. Если в result записывается 0, редактор считает, что операция была завершена успешно. Для того, чтобы просигнализировать об ошибке нужно выставить result в ненулевое значение. В случае, если result > 0, редактор считает, что плагин уже проинформировал пользователя о возникшей ошибке самостоятельно, если же он < 0, редактор выведет стандартный диалог с сообщением об ошибке.

3  Функции обратного вызова (callback-функции)

С помощью callback-функций плагин может "общаться" с редактором и получать доступ к некоторым его специальным возможностям. Callback-функций существует весьма значительное количество, все они подробно описаны в документации, прилагаемой к SDK. Мы опишем здесь несколько наиболее часто используемых callback-функций.

AdvanceStateProc() - вызывается для передачи управления редактору между этапами работы плагина. Она сигнализирует, что часть работы уже сделана и говорит редактору о том, что нужно сделать следующий шаг во взаимодействии с плагином (например, обновить или перечитать поля управляющей струкуры). AdvanceState используется, если плагин выполняет обработку изображения не целиком, а поэтапно, в несколько шагов. Такое может произойти в случае обработки большого изображения в условиях ограниченного объема доступной памяти, недостаточной для обработки изображения целиком. Подробнее об использовании AdvanceState в секции 5.2

DisplayPixelsProc() - служит для вывода на экран (в окно) фрагмента изображения. Она самостоятельно производит перевод из внутреннего представления изображения в редакторе (включая перевод в нужное цветовое пространство) в режим, совместимый с режимом дисплеем (производя dithering, если это необходимо). Используется, например, для организации собственного окна preview в диалоге плагина.

TestAbortProc() - эта функция должна вызываться несколько раз в секунду во время фильтрации изображения, если фильтрация занимает значительное время. Это нужно для того чтобы у пользователя была возможность прервать работу плагина и редактор не "подвисал". Если TestAbortProc() возвращает "true", фильтрация должны быть прервана. Как побочный эффект, эта функция меняет курсор редактора на песочные часы и периодически их переворачивает.

UpdateProgressProc() - эту функцию можно использовать во время выполнения фильтрации для того, чтобы обновлять индикатор прогресса обработки, отображаемый редактором.

4  Работа с памятью

В Photoshop'е используется собственный менеджер памяти. Это означает, что редактор использует собственный алгоритм перемещения участков своего виртуального пространства памяти между диском и физической оперативной памятью. Этот алгоритм организован таким образом, чтобы менеджер виртуальной памяти Windows не вмешивался в этот процесс. Для того, чтобы не нарушить работу менеджера памяти редактора, плагин должен заключить с ним определенные соглашения по использованию физической оперативной памяти в процессе своей работы и соблюдать их. "Обсуждение" этих соглашений для фильтрационных плагинов происходит во время вызова функции ENTRYPOINT с параметром selector = filterSelectorPrepare (см. секцию 5.1). Во время этого вызова редактор сообщает максимальный размер физической оперативной памяти, который может быть предоставлен плагину (через параметр maxSpace структуры pluginParam) . Плагин должен таким образом рассчитать алгоритм своей работы, чтобы не вылезать за границы предоставленного объема. Для того чтобы не превысить лимит отведенного пространства обычно производится обработка изображения по частям, например по блоками по 64x64 или 128x128 пикселей. Если плагин планирует выделять достаточно большие буфера в процессе своей работы (более 32 килобайт), он либо должен сообщить об этом редактору, установив поле bufferSpace структуры pluginParam равному суммарному размеру требуемых буферов, либо использовать для выделения памяти callback-функции, предоставляемые редактором (они входят в наборы Handle и Buffer Callback suite - см. документацию Photoshop SDK [1]). В файле PIUtilites.cpp, поставляемом вместе с примерами Photoshop SDK дан набор функций (HostNewHandle, HostDisposeHandle, HostLockHandle, HostUnlockHandle, etc.) для выделения и освобождения блоков памяти, которые используют callback-функции редактора если редактор их поддерживает, и системные вызовы Windows - если нет. Их использование позволяет не беспокоиться о наличии Handle Callback Suite у редактора - в случае их остутствия автоматически будут использованы функции Windows и плагин проработает корректно.

Нужно особо отметить, что в pluginParam->maxSpace указывается не объем памяти, которую плагин может выделять для своих нужд, а максимальный объем всей физической оперативной памяти, которую может использовать плагин при обработке: maxSpace = (input area size + output area size + mask area size + bufferSpace).

Если плагин использует собственные данные, которые хочет сохранить между вызовами функции ENTRYPOINT (например набор глобальных переменных), то он должен присвоить дескриптор (handle) блока памяти, в котором они хранятся, полю pluginData. Редактор будет сохранять значение этого поля между последовательными вызовами плагина. Не нужно хранить задаваемые пользователем настройки фильтра внутри блока, хранящегося в pluginData. Для этого существует специальное поле parameters структуры pluginParam, которому нужно присвоить дескриптор (handle) структуры, хранящей параметры плагина.

5  Порядок взаимодействия редактора и фильтрационного плагина

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

5.1  Подготовка к работе

  • filterSelectorParameters

    В редакторе существует два способа вызова фильтрационных плагинов - либо через пункт меню, соответствующий данному плагину в одной из категорий меню Filter, либо через пункт меню "Last Filter" (повтор последней операции). В случае инициирования не через LastFilter, вызов filterSelectorParameters является первым вызовом функции ENTRYPOINT. Цель этого вызова - создать и инициализировать структуру, хранящую параметры работы плагина, задававаемые пользователь. Дескриптор этой структуры нужно сохранить в специальном поле pluginParam->parameters. При вызове filterSelectorParameters редактор устанавливает это поле равным NULL. Параметры, устанавливаемые на этом этапе не должны зависеть от размера, режима изображения или размера обрабатываемой области.

  • filterSelectorPrepare

    Этот вызов является первым в случае, если фильтр инициируется из пункта меню "Last Filter" (в таком случае параметры обработки запоминаются во время предыдущего использования плагина). Во время этого вызова плагин может скорректировать действия алгоритма Photoshop по распределению памяти. Поле pluginParam->maxSpace указывает на максимальное количество байт физической оперативной памяти, которое редактор может предоставить плагину. Плагин может уменьшить это количество для увеличения эффективности работы редактора. Подробнее по поводу работы с памятью сказано в секции 4.

    На этом этапе в структуре pluginParam уже определены поля imageSize, planes и filterRect, которые можно использовать для расчета необзодимого объема памяти для проведения обработки. В случае, если плагин собирается выделять память свыше 32 килобайт, следует установить поле bufferSpace равным объему требуемой памяти, для того, чтобы редактор попробовал освободить необходимое плагину количество физической оперативной памяти. Другой вариант - установить bufferSpace в 0 и для выделения памяти использовать callback-процедуры предоставляемые редактором (из Buffer Callback suite илм Handle Callback suite).

5.2  Фильтрация изображения

  • filterSelectorStart

    Во время этого вызова выводится диалог плагина (если он предусмотрен) для модификации параметров фильтрации, задаваемых пользователем. Диалог нужно выводить только в том случае, если первым обращением к функции ENTRYPOINT был filterSelectorParameters, а не filterSelectorPrepare. Модифицированные пользователем параметры нужно сохранить в поле parameters структуры pluginParam.

    Следующим шагом ялвяестcя собственно обработка изображения. Перед началом фильтрации нужно обязательно проверить значения параметров обработки (хранящихся в pluginParam->parameters), для того чтобы избежать ошибочного завершения программы в случае некорректных значений параметров. Обработка изображения происходит следующим образом: плагин запрашивает определенные фрагменты входного и выходного изображения для обработки, устанавливая определенные поля в структуре pluginParam: inRect, outRect, maskRect, inLoPlane, inHiPlane, outLoPlane, outHiPlane и передавая управление редактору (см. далее). После этого фрагменты изображения для осуществления фильтрации становятся доступны через поля pluginParam - inData, outData, maskData.

    Организация взаимодействия через AdvanceState

    Как уже было сказано, для того чтобы не нарушать работу алгоритма распределения памяти Photoshop желательно обрабатывать большие изображения по частям. В случае, если редактор поддерживает механизм AdvanceState, то осуществить пофрагментную обработку всего изображения можно внутри одного вызова filterSelectorStart. Для обработки очередного фрагмента, необходимо установить поля inRect, outRect и maskRect равными границам обрабатываемого фрагмента. Затем вызвать advanceState callback-процедуру, для того чтобы запросить у редактора эти фрагменты для обработки. Если advanceState возвратила код успешного завершения - произвести фильтрацию фрагмента, в противном случае - прервать обработку и выйти. В цикле обработки фрагментов нужно время от времени вызывать abortProc callback-процедуру для проверки не нужно ли прервать процедуру фильтрации. После того как всё изображение обработано, следует установить inRect=outRect=maskRect=(0, 0, 0, 0), сигнализируя редактору, что обработка закончена.

    Организация взаимодействия без AdvanceState

    Механизм AdvanceState начал поддерживаться начиная с версии 3.0 редактора. Поэтому существует другой (более старый и менее удобный) вариант организации обработки изображения по частям. Он заключается в том, что редактор повторно (сколько потербуется раз) вызывает функцию ENTRYPOINT с параметром selector=filterSelectorContinue, указвающим на режим обработки изображения. В таком случае плагин должен обрабатывать лишь часть изображения за один вызов и выходить из функции обработки ожидая следующего вызова. Если механизм AdvanceState не поддерживается редактором или плагином, то обработку изображения следует расположить в обработке вызова ENTRYPOINT filterSelectorContinue. В filterSelectorStart следует инициализировать фильтр и установить inRect, outRect и maskRect равным границы первого обрабатываемого фрагмента, после чего выйти из плагина.

  • filterSelectorContinue

    Внутри обработки вызова filterSelectorContinue нужно обработать текущий фрагмент изображения, и установить inRect, outRect и maskRect равным границы следующего запрашиваемого для обработки фрагмента. Процедура ENTRYPOINT с параметром selector равным filterSelectorContinue будет вызываться редактором до тех пор, пока хотя бы один из прямоугольников inRect, outRect и maskRect не пуст, поэтому после обработки всего изображения их следует установить в (0, 0, 0, 0).

5.3  Завершение работы

  • filterSelectorFinish

    Этот вызов позволяет совершить очистку и освобождение выделенных плагином ресурсов. Он вызывается в том и только том случае, если вызов filterSelectorStart плагина возвращает редактору код успешного завершения. Если редактор обнаруживает нажатие клавиши escape между вызовами filterSelectorContinue он вызывает filterSelectorFinish (вместо следующего filterSelectorContinue), до завершения операции фильтрации. Обработка такой ситуации должна быть предусмотрена плагином.

6  Важные поля структуры, передающийся через
pluginParam

Нет смысла дублировать таблицу, приведенную в главе документации к Photoshop SDK, в которой подробно описаны все поля структуры FilterRecord, передающейся фильтрационным плагинам через pluginParam. Остановимся лишь на наиболее интересных и не вполне очевидных, чтобы не пропустить их среди длинного списка.

  • parameters - если у плагина есть параметры функионирования, которые может задавать пользователь, то при вызове filterSelectorParameters он должен выделить блок памяти для их хранения и дескриптор этого блока записать в это поле. Изначально parameters = NULL.
  • maxSpace, bufferSpace - поля, используемые для достижения договоренности между плагином и редактором по вопросам используемой плагином оперативной памяти (см. секцию 4).
  • inRect, outRect, inLoPlane, inHiPlane, outLoPlane, outHiPlane - поля через которые плагин запрашивает для обработки конкретные фрагменты (и цветовые плоскости) входного и выходного изображения. Можно запрашивать области, выходящие за границы изображения, если это требуется. Массивы данных входного и выходного изобаржения доступны плагину через указатели inData и outData. Поля inRowBytes и outRowBytes задают длину одной строки изображения в байтах.
  • При обработка не всего изображения, а только выбранной пользователем области (selection) плагину предоставляется информация о границах области, которую ему нужно обработать. В поле filterRect хранится ограничивающий прямоугольник области, которую нужно обработать. В случае, если выбрана непрямоугольная область, устанавливается флаг haveMask. Обычно, редактор работает в режиме, когда он самостоятельно отбрасывает все изменения, произведенные плагином вне области обработки (в таком случае, флаг autoMask устанавливается в TRUE). Выставлением флага определенного флага в ресурсах плагина или в явном виде выставляя autoMask = FALSE плагин может самостоятельно определять какие пиксели изображения попадают в область обработки. Для этого ему передается изображение - маска, доступ к которому осуществляется также как и к входному и выходному изображениям через поля maskRect, maskData, maskRowBytes.

  • Свойства изображения - количество каналов, цветовая модель, битовая глубина каналов задаются через поля planes, imageMode и depth.

  • Часто, при фильтрации пикселей вблизи границ изображения требуется проводить проверку на то, чтобы не затронуть пиксели вне изображения и организовывать особую обработку таких случаев. Для того, чтобы избежать усложнения собсвенного кода, можно запрашивать у редактора прямоугольники для обработки, выходящие за границы изображения. В случае, если редактор выставил флаг supportsPadding можно заказать заполнение "фальшивых" пикселей за границами изображения конкретными значениями через поля inputPadding, outputPadding, maskPadding. Или (через эти же поля) можно выставить особый режим работы с пикселями вне изображения: plugInWantsEdgeReplication - репликация границ изображения, plugInDoesNotWantPadding - заполнение случайными значениями, plugInWantsErrorOnBoundsException - генерацию программного исключения с аварийным завершением плагина в случае запроса прямоугольника, выходящего за границы изображения.

7  Оформление ресурсов плагина

В ресурсах плагина прописывается множество важной информации - начиная от сигнатур, по которым Photoshop "принимает плагин за своего" и заканчивая указанием поддерживаемых плагином режимов изображения (image modes). Ресурсы плагинов задаются в формате Macintosh и переводятся в формат Windows с помощью утилиты CNVTPIPL.EXE, входящей в комплект Photoshop SDK. Существуют два типа ресурсов плагинов Adobe Photoshop - 'PiMI' (произносится "пимми") и 'PiPL' (произносится "пипл") ресурсы. Ресурсы 'PiMI' поддерживались в ранних версиях Adobe Photoshop (< 3.0), затем были заменены на 'PiPL' ресурсы (начиная с весрии 3.0). Поддержка 'PiMI' в поздних версиях редактора осуществлена для сохранения совместимости со старыми плагинами. Рекомендуется включать в плагин ресурсы обоих типов для возможности работы плагина как с ранними так и с поздними версиями редактора.

7.1  Ресурсы 'PiMI'

Ресурс 'PiMI' имеет фиксированную структуру, хорошо описанную в документации в SDK. Информация содержащаяся в ресурсе, в том числе включает в себя версию и подверсию плагина и флаги, показывающие поддерживаемые плагином режимы изображения (image modes).

7.2  Ресурсы 'PiPL'

Ресурс 'PiPL' имеет более сложную, расширяемую структуру. Он организован в виде списка свойств плагина. Общими для всех типов плагинов является несколько свойств, включая: PIKindProperty, задающее тип плагина; PIVersionProperty, задающее версию плагина, SupportedModes, задающее какие плагин поддерживает режимы изображения (image modes); EnableInfo, задающее при каких условия пункт меню вызывающий плагин доступен пользователю (способ задания этого свойства подробно описан в документе Cross-Application Plug-in Development Resource Guide); PICategoryProperty - для фильтрационных плагинов задающее категорию меню, куда поместить вызов плагина; PINameProperty - текст пункта меню, вызывающего данный плагин; PIWin32X86CodeDesc - имя процедуры-точки входа в dll плагина.

Для фильтрационных плагинов задается свойство PIFilterCaseInfoProperty, регулирующее случаи обработки многослойных (multi-layer) изображений. Это свойство задает поддерживаемые плагином режимы многослойности. В Photoshop >= 3.0 слои состоят из цветовой информации и информации о прозрачности каждого пикселя. Прозрачные пиксели имеют неопределенный цвет. В PIFilterCaseInfoProperty для семи вариантов режима изображения (наличие/отсутствие многослойности, наличие/отсутствие выбранной пользователем области обработки, разрешение/запрещение редактирования плагином карты прозрачности слоя) задаются флаги, показывающие поддерживает ли плагин такой режим и требуется ли какя-либо предобработка данных изображения перед обработкой их плагином. Подробнее о PIFilterCaseInfoProperty см. документацию к Photoshop SDK [2] и примеры поставляемых вместе с SDK.

8  Заключение

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

Список литературы

[1]
Andrew Coven, David J. Wise, Seetharaman Narayanan, Paul D. Ferguson, Thomas Ruark, Tina Wu, Äpplication Programming Interface Guide", Adobe System Incorporated, 1999.
[2]
Brian Andrews, Andrew Coven, Thoms Ruark, Bruce Bullis, "Cross-Application Plug-in Development Resource Guide", Adobe System Incorporated, 1999.

Оставить комментарий

Комментарий:
можно использовать BB-коды
Максимальная длина комментария - 4000 символов.
 
Реклама на сайте | Обмен ссылками | Ссылки | Экспорт (RSS) | Контакты
Добавить статью | Добавить исходник | Добавить хостинг-провайдера | Добавить сайт в каталог