|
На главную Пишем плагинСоздаем библиотеку Flip.dpr. Напишем сначала основную процедуру плагина: procedure ENTRYPOINT(selector : smallint;
var param : FilterRecord;
var data : integer;
var result: smallint); cdecl;
begin
resultCode := noErr;
case selector of
filterSelectorAbout: DoAbout;
filterSelectorParameters: DoParameters(param);
filterSelectorPrepare: DoPrepare(param);
filterSelectorStart: DoStart(param);
filterSelectorContinue: DoContinue(param);
filterSelectorFinish: DoFinish(param);
else
resultCode := filterBadParameters;
end;
{ Нужно не забывать инициализировать переменную result при каждом
вызове плагина }
result := resultCode;
end;
В переменной selector нам передается код запрашиваемого действия. Каждое действие будет обрабатывать отдельная процедура. В записи param передаются параметры изображения и всякая другая информация. Переменную data мы никак не будем использовать. Для хранения значения параметра result будем использовать глобальную переменную resultCode. Это удобней и быстрей, чем все время передавать ссылку в параметрах процедур. Только нужно не забывать всегда инициализировать переменную (первая строчка процедуры) и возвращать значение редактору (последняя строчка). Теперь реализуем процедуры, обрабатывающие разные действия (по значению selector). DoAbout. Действие на запрос вывода диалога About плагина. Забудем пока про рекомендации по оформлению этого диалога и обойдемся просто процедурой MessageBox. procedure DoAbout; begin MessageBox(0, 'Мой первый фильтр.', 'Flip', MB_OK); end; DoParameters. Выводим пользователю диалог задания параметров. Обойдемся простым MessageBox с двумя кнопками: YES и NO. Если пользователь отменит обработку изображения, то вернем редактору код userCanceledErr. procedure DoParameters(var param : FilterRecord);
var
ans : integer;
begin
ans := MessageBox(0, 'Развернуть картинку?', 'Flip', MB_YESNO);
case ans of
0: begin
MessageBox(0, 'Невозможно загрузить диалог.',
'Ошибка', MB_OK);
resultCode := userCanceledErr;
end;
IDYES:
resultCode := noErr;
else
resultCode := userCanceledErr;
end;
end;
При вызове плагина на этом этапе пользователь увидит такое окно: ![]() DoPrepare. Здесь нужно вычислить необходимый плагину размер памяти, но мы ничего делать не будем. procedure DoPrepare(var param : FilterRecord); begin end; DoStart. Вообще, в целях экономии ресурсов нужно обрабатывать изображение кусками, но для простоты запросим сразу все изображение. Запишем в поля param.inRect (исходное изображение) и param.outRect (результат) размеры всего изображения. Обратите внимание, что у каждого угла сначала указывается координата Y, а потом X. Если выделить прямоугольную часть изображения, то правый край выделения будет проходить по правым границам выделенных пикселей и правая координата выделения будет на 1 больше, чем максимальная координата выделенных пикселей. Аналогично с нижним краем. Т.е. горизонтальные координаты пикселей изменяются в диапазоне от 0 до param.imageSize.h - 1, но координаты соответствующего выделения будут 0 и param.imageSize.h. procedure DoStart(var param : FilterRecord); begin SetRect(param.inRect, 0, 0, param.imageSize.v, param.imageSize.h); param.outRect := param.inRect; param.inLoPlane := 0; param.inHiPlane := param.planes - 1; param.outLoPlane := 0; param.outHiPlane := param.planes - 1; end; Мы использовали процедуру SetRect. Напишем ее. Еще раз обращаю внимание на порядок задания параметров (сначала Y, а потом X - именно в таком порядке задаются поля записи Rect, будем следовать принятым в Photoshop соглашениям). procedure SetRect(var r : Rect; top, left, bottom, right : smallint); begin r.top := top; r.left := left; r.bottom := bottom; r.right := right; end; DoContinue. Редактор может несколько раз вызывать эту операцию, пока хотя бы одно из полей inRect, outRect или maskRect указывает на непустую часть изображения. Мы обрабатываем изображение сразу целиком и процедура вызовется всего один раз. procedure DoContinue(var param : FilterRecord);
type
DataBuffer = array [0..1000000000] of byte;
var
x, y, p : integer;
inData : ^DataBuffer;
outData : ^DataBuffer;
begin
inData := param.inData;
outData := param.outData;
{ Переворачиваем изображение }
for y := 0 to param.imageSize.v - 1 do
for x := 0 to param.imageSize.h - 1 do
for p := 0 to param.planes - 1 do
outData[param.outRowBytes*y + param.planes*x + p] :=
inData[param.inRowBytes*y +
param.planes*(param.imageSize.h - x - 1) + p];
SetRect(param.inRect, 0, 0, 0, 0);
param.outRect := param.inRect;
param.maskRect := param.inRect;
end;
DoFinish. Здесь можно произвести какие-нибудь завершающие действия для своих нужд. procedure DoFinish(var param : FilterRecord); begin end; Теперь укажем компилятору расширение библиотеки 8bf, присоединим ресурсы, подключим модули, объявим переменную resultCode и экспортируем процедуру ENTRYPOINT: library Flip;
{$E 8bf}
{$R Flip_prop.res}
uses
Windows,
PITypes,
PIFilter;
var
resultCode : smallint;
{ ... здесь должны быть описанные выше процедуры }
exports
ENTRYPOINT;
end.
Для компиляции плагина понадобятся модули PITypes.pas, PIGeneral.pas и PIFilter.pas. Эти модули я написал на основе аналогичных заголовочных файлов PITypes.h, PIGeneral.h и PIFilter.h из Adobe Photoshop 6.0 SDK. Назад | Содержание | Вперед
© Ярослав Музыкантов muzykantov@mail.ru |