Tvorba zásuvných modulů pro Adobe Photoshop Jiří Skála, 2006 js.1@seznam.cz
O pluginech obecně programové moduly rozšíření stávající aplikace (plugin host) přidávány nebo modifikovány nezávisle první představení pluginů Apple: HyperCard lepení modulů přímo do aplikace Silicon Beach: Digital Darkroom, SuperPaint moduly jako samostatné soubory Adobe: Photoshop výhody uživatelské, programátorské aplikace poskytuje pluginu prostředí (I/O, GUI, správa paměti,...) 2/25
Pluginy pro Photoshop Macintosh Windows typy pluginů automation color picker import, export extension filter format parser selection 3/25
Rozhraní pluginu DLL knihovna provedení pluginu několik volání jediný vstupní bod DLLExport MACPASCAL void PluginMain( const short selector, void* pluginparamblock, long* plugindata, short* result) selector = 0 místo pluginparamblock předán AboutRecord zobrazit okno O pluginu 4/25
Hlášení chyb nula (noerr) všechno v pořádku kladné číslo chyba, hlášení zobrazil plugin záporné číslo chyba, hlášení zobrazí plugin host symbolické konstanty, chybové kódy OS 5/25
Filter Parameter Block struktura FilterRecord obousměrná komunikace mezi pluginem a hostem výběr nejdůležitějších položek parameters imagesize, imagemode, planes, depth maxspace, bufferspace filterrect, in/outrect, in/outdata in/outtilewidth, in/outtileheight in/outloplane, in/outhiplane, wantsabsolute havemask, maskrect, maskdata input/maskrate, input/output/maskpadding in/out/maskrowbytes ukazatele na funkce 6/25
Volání filtr pluginu Parameters FilterRecord neúplný inicializovat parametry, měly by být nezávislé na formátu obrazu nastavit značku, aby se zobrazil konfigurační dialog Filter Last Filter filterselectorparameters filterselectorprepare filterselectorstart Prepare FilterRecord neúplný stanovit paměťové nároky maxspace, bufferspace dostupná paměť nemusí být v celku filterselectorcontinue filterselectorfinish 7/25
Volání filtr pluginu Start ověřit parametry (filterbadparameters) zkontrolovat formát obrazu (filterbadmode) zjistit dostupnost funkcí (errpluginhostinsufficient) pokud je potřeba, zobrazit dialog s nastavením (usercancelederr) nastavit parametry zpracování obrazu wantsabsolute = true; inputrate = (int32)(1 << 16); inputpadding = pluginwantsedgereplication; 8/25
Volání filtr pluginu Start zpracování obrazu po blocích (intilewidth, intileheight) stanovit rozsah vstupu / výstupu (in/outrect, maskrect, in/outloplane, in/outhiplane) aktualizovat stav *gresult = gfilterrecord->advancestate(); if (*gresult!= noerr) return; zpracovat aktuální blok pozor na zarovnání řádků (in/outrowbytes, maskrowbytes) 9/25
Volání filtr pluginu Start čas od času zkontrolovat případné přerušení filtru if (gfilterrecord->abortproc()) { *gresult = usercancelederr; return; } čas od času aktualizovat progress bar gfilterrecord->progressproc( ++progressdone, progresstotal); nakonec vynulovat inrect, outrect, maskrect (všechny tři) 10/25
Volání filtr pluginu Continue pokračovat ve zpracovávání obrazu nakonec vynulovat inrect, outrect, maskrect (všechny tři) Finish úklid po dokončení pluginu pokud při fázi Start nenastane chyba, je zaručeno zavolání Finish 11/25
Funkce plugin hosta ukazatele v Plugin Parameter Block před použitím se ujistit, že jsou dostupné přímé OSErr advancestate(void) Boolean abortproc(void) void progressproc(long done, long total) OSErr colorservices(colorservicesinfo *info) OSErr displaypixels(pspixelmap *source, VRect *srcrect, int dstrow, int dstcol, unsigned platformcontext) 12/25
Funkce plugin hosta ukázka použití color services ColorServicesInfo csinfo; csinfo.infosize = sizeof(csinfo); csinfo.selector = plugincolorservicesconvertcolor; csinfo.sourcespace = CSModeToSpace(gFilterRecord->imageMode); csinfo.resultspace = plugincolorservicesrgbspace; for (int a = 0; a < 4; a++) csinfo.colorcomponents[a] = color[a]; if (gfilterrecord->colorservices(&csinfo) == noerr) for (int b = 0; b < 4; b++) color[b] = (uint8)csinfo.colorcomponents[b]; 13/25
Funkce plugin hosta sdružené v sadách (suites) Buffer suite int spaceproc(void) OSErr allocateproc(int size, BufferID *buffer) void freeproc(bufferid buffer) Ptr lockproc(bufferid buffer, Boolean movehigh) void unlockproc(bufferid buffer) data z bufferu přetypovat na uint8 14/25
PiPL Plug-In Property List metadata pluginu, identifikace, statická nastavení resource, Macintosh Rez formát, konverze pro Windows základní informace a nastavení jméno pluginu, typ, kategorie, verze rozhraní vstupní bod podporované formáty obrazu interpretace průhlednosti, zpracování průhledných pixelů 15/25
PiPL resource 'PiPL' (ResourceID, "Invert PiPL", purgeable) { { Kind {Filter}, Name {"Invert..."}, Category {"Invert"}, Version {(latestfilterversion << 16) latestfiltersubversion}, CodeWin32X86 {"PluginMain"}, 16/25
PiPL SupportedModes { nobitmap, doessupportgrayscale, noindexedcolor, doessupportrgbcolor, doessupportcmykcolor,... }, EnableInfo { "in (PSHOP_ImageMode," "GrayScaleMode, RGBMode, CMYKMode,...)" }, 17/25
PiPL FilterCaseInfo { { /* Flat data, no selection */ instraightdata, outstraightdata, donotwriteoutsideselection, doesnotfilterlayermasks, doesnotworkwithblankdata, donotcopysourcetodestination,... } } } }; 18/25
Nastavení projektu MS Visual Studio překládat jako DLL nastavit příponu.8bf nastavit adresáře s hlavičkovými soubory utility vložit zdrojové soubory do projektu linkovat s knihovnou version.lib PiPL custom build step připravit preprocesorem C (cl.exe) převést do Windows formátu (cnvtpipl.exe) přidat do resource (.rc) 19/25
Ladění v MS Visual Studio zkopírovat plugin v rámci Post Build Event zvolit aplikaci (Photoshop.exe) v nastavení projektu nebo zadat při prvním spuštění po aktualizaci stávajících pluginů není nutné restartovat Photoshop nejčastější chyby Photoshop plugin vůbec nenajde chybí PiPL index mimo rozsah pole ne všechny obrazy jsou RGB 20/25
Adobe Dialog Manager implementace dialogových oken nezávisle na platformě konzistentní Adobe look and feel design dialogu se načte z resource k dispozici jsou sady funkcí (suites) sady nutno získat, po použití uvolnit gfilterrecord->sspbasic-> AcquireSuite( kadmdialogsuite, kadmdialogsuiteversion, (void**)&sadmdialog); gfilterrecord->sspbasic->releasesuite( kadmdialogsuite, kadmdialogsuiteversion); 21/25
Adobe Dialog Manager vytvoření dialogového okna sadmdialog->modal(pluginref, "SetupDialog", SETUP_DIALOG, kadmmodaldialogstyle, DialogInit, NULL); vrací ID ovládacího prvku, kterým byl dialog uzavřen (typicky tlačítko OK nebo Storno) 22/25
Adobe Dialog Manager přístup k prvkům dialogu ADMItemRef item; item = sadmdialog->getitem(dlgref, ID_CHECKBOX); sadmitem->setbooleanvalue(item, true); item = sadmdialog->getitem(dlgref, ID_OK); sadmitem->setnotifyproc(item, ButtonOkNotify); 23/25
Adobe Dialog Manager notifier přístup k událostem na vyšší úrovni spuštěn po dokončení interakce s uživatelem void ASAPI ButtonOkNotify( ADMItemRef itemref, ADMNotifierRef notifier) { sadmitem->defaultnotify(itemref, notifier); } if (sadmnotifier->isnotifiertype( notifier, kadmuserchangednotifier)) {... } 24/25
Adobe Dialog Manager tracker přístup k událostem na nižší úrovni ASBoolean SliderTrack( ADMItemRef itemref, ADMTrackerRef tracker) { sendnotify = sadmitem->defaulttrack( itemref, tracker); if (sadmtracker->testaction( tracker, kadmmousemoveddownaction)) {... } } return sendnotify; 25/25