Tvorba zásuvných modulů pro Adobe Photoshop
Jiří Skála, 2006
[email protected]
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 Filter
•
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
•
Last Filter
filterSelectorParameters
filterSelectorPrepare
filterSelectorStart
Prepare – FilterRecord neúplný
filterSelectorContinue
– stanovit paměťové nároky – maxSpace, bufferSpace – dostupná paměť nemusí být v celku
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