Dans l'article précédent, nous avons présenté certains des concepts et bases les plus élémentaires pour le développement de plug-ins de filtres Photoshop. Ps Afin de répondre aux besoins applicatifs du plug-in, il fournit également un grand nombre de fonctions (ou services) de rappel pour le plug-in. Par exemple, un filtre peut enregistrer les paramètres définis par le dernier utilisateur après un appel et les appliquer au prochain appel ou affichage de l'interface utilisateur. Cela se fait via la fonction de rappel de Ps. Dans cet article, nous expliquerons certaines des fonctions de rappel PS les plus importantes. Après avoir compris cet article, nous pourrons utiliser les fonctions de rappel pour effectuer le travail nécessaire tel que le stockage de nos paramètres de filtre. Cet article sera beaucoup plus complexe et approfondi que le premier, mais en même temps, à partir de cet article, nous pourrons également avoir un aperçu des secrets internes de PS : une conception soignée du système, une interface parfaite et un mécanisme de travail complexe.
(1) Classification des fonctions de rappel :
Les fonctions de rappel Ps peuvent être divisées en deux types selon leur position :
(1) Rappel direct : (peut être appelé directement fonctions de rappel)
Ces fonctions de rappel sont des membres directs de FilterRecord et peuvent être obtenues directement à partir des paramètres FilterRecord. Par exemple, AdvanceStateProc (mise à jour des données), TestAbortProc (annulation de l'utilisateur test), etc., entrent dans cette catégorie.
(2) Suite de rappel : (ensemble de fonctions de rappel)
L'ensemble de fonctions de rappel fourni en classant les fonctions de rappel en fonction de leurs fonctions est un ensemble de fonctions de rappel. C'est un pointeur qui pointe vers un ensemble de fonctions de rappel. La structure (struct) de la fonction de rappel, nous pouvons obtenir un certain ensemble de fonctions de rappel à partir de FilterRecord, puis appeler la fonction qu'il contient.
Les principaux ensembles de fonctions de rappel actuellement fournis sont :
Buffer Suite : Gestion de la mémoire cache (application et libération de l'espace cache).
UI Hook Suite : un ensemble de fonctions liées aux opérations de l'interface utilisateur.
Channel Ports Suite : lecture et écriture du port de canal, utilisé pour lire et écrire les données de sélection réelles dans PS ! Au lieu d'une copie copie.
. Color Space Suite : Service d'espace colorimétrique (conversion des couleurs, etc.).
Handle Suite : Gestion des handles (handle encapsulé PS et gestion de la mémoire, similaire à la suite Buffer).
Suite d'erreurs : recevoir et afficher des messages d'erreur aux utilisateurs (reçoit différents types de chaînes de messages d'erreur).
Suite GetFileList : obtenez une liste de fichiers (récupérez des fichiers, appelez le navigateur pour naviguer sur le Web, etc.).
GetPath Suite : obtenez le chemin.
ZString Suite : encapsule le traitement des chaînes.
Par exemple, UI Hook Suite fournit un ensemble de fonctions de rappel liées à l'interface utilisateur. Sa première version était définie comme :
UI Hooks Suite Version1
#define kPSUIHooksSuiteVersion1 1 1 // version suite
typedef struct
{
ProcessEventProc processEvent;
DisplayPixelsProc displayPixels;
ProgressProc progressBar;
TestAbort Proc testAbort;
MainAppWindowProc MainAppWindow;
HostSetCursorProc SetCursor;
HostTickCountProc TickCount;
PluginNameProc GetPluginName;
} PSUIHooksSuite1;
Veuillez noter que certaines fonctions de rappel sont des rappels directs et sont stockées dans une suite , tels que testAbout et displayPixels. Je suppose qu'au début, ces pointeurs de fonction ont été ajoutés à FilterRecord, mais avec la mise à niveau, de plus en plus de fonctions de rappel ont été ajoutées, ce qui entraînerait la mise à niveau et l'ajout continus de FilterRecord, ce qui rendrait la maintenance difficile, alors Adobe a commencé à ajouter un rappel. La classification des fonctions est divisée en plusieurs suites, et seule la suite est placée dans FilterRecord. De cette façon, lors de l'ajout d'une fonction, il vous suffit de l'ajouter à la suite correspondante et de mettre à niveau la suite sans affecter le FilterRecord. De cette manière, certaines premières fonctions de rappel sont situées à deux emplacements en même temps, FilterRecord et la suite à laquelle elles appartiennent, afin de pouvoir être appelées directement ou via la suite correspondante.
(2) Suite PEA (module de gestion d'ensemble de fonctions de plug-in (couche), le nom que j'ai traduit est sujet à discussion)
Suite PEA est un système de plug-in utilisé par certains logiciels de la série Adobe. Il fournit une couche centrale de gestion des plug-ins commune pour le programme hôte et une interface standard pour les plug-ins.
La légère différence avec l'appel direct est que l'ensemble de fonctions doit être acquis (Acquis) avant utilisation et que la suite doit être publiée (release) après utilisation.
Un ensemble de fonctions obtenu est essentiellement un pointeur de structure, pointant vers une structure contenant un ensemble de pointeurs de fonction, donc lorsque nous appelons une fonction, la forme est la suivante :
sSuite->function( );
Par conséquent, l'appel d'une fonction dans l'ensemble de fonctions de rappel est le suivant :
Acquisition et sortie de la suite
ADMBasicSuite *sADMBasic;
//Obtenir ADMBasic Suite :
filterParamBlock->sSPBasic->AcquireSuite(
kADMBasicSuite,
kADMBasicSuiteVersion,
&sADMBasic);
//Appeler
sADMBasic->Bip( );
// Release
filterParamBlock->sSPBasic->ReleaseSuite(
kADMBasicSuite,
kADMBasicSuiteVersion);
(3) Introduction à certaines des fonctions de rappel les plus importantes
Ensuite, nous présenterons quelques fonctions de rappel qui, à mon avis, sont plus importantes pour plug-ins de filtrage . Présentez brièvement l’emplacement et l’utilisation de ces fonctions de rappel.
3.1 DisplayPixelsProc( )
Fonction : Sortie de données de pixels (dessiner une image) à la position spécifiée sur le DC spécifié. (Bien sûr, nous pouvons remplir cette fonction nous-mêmes.)
Emplacement : Direct Callback, UI Hook Suite ;
Définition :
OSErr (*DisplayPixelsProc) (const PSPixelMap *source ,
const VRect *srcRect, int32 dstRow, int32 dstCol,
unsigned32 platformContext); 🎜>
Mise en évidence de code produite par Actipro CodeHighlighter (freeware)http://www.php.cn/-->typedef
typedef struct PIDescriptorParameters
{
int16 descriptorParametersVersion ; Drapeau de lecture d'action : 0-boîte de dialogue facultative ; 1-boîte de dialogue requise ; 2-pas de boîte de dialogue ; int16 ; recordInfo;
//Drapeau d'enregistrement d'action : 0-la boîte de dialogue n'est pas affichée ; 1-la boîte de dialogue est affichée ; 2-la boîte de dialogue est silencieuse ; > Descripteur PIDescriptorHandle ; //
Le handle du descripteur est très important, nous l'utiliserons pour lire et écrire des données ! WriteDescriptorProcs*
writeDescriptorProcs //"écrire" sous- function Set
ReadDescriptorProcs* readDescriptorProcs //"lire" sous Ensemble de fonctions
} PIDescriptorParameters;Ensuite, nous pouvons obtenir l'ensemble de sous-fonctions « lire » ou « écrire » :
Obtenir la sous-suite « lire » et « écrire »
//Obtenir la structure des paramètres du descripteur :
PIDescriptorParameters* descParams = gFilterRecord- >descriptorParameters;
if (descParams == NULL) return err;
//Obtenir l'ensemble de sous-fonctions "lire" :
ReadDescriptorProcs* readProcs = gFilterRecord-> descriptorParameters ->readDescriptorProcs;
if (readProcs == NULL) return err;
//Obtenir l'ensemble de sous-fonctions "écrire" :
WriteDescriptorProcs* writeProcs = gFilterRecord-> descriptorParameters->writeDescriptorProcs;
if (writeProcs == NULL) retour err;
Après avoir obtenu deux ensembles de sous-fonctions, nous pouvons appeler les fonctions sous les ensembles de sous-fonctions correspondants pour « lire » et « écrire » nos paramètres. L'utilisation des deux sous-ensembles de fonctions est similaire à l'opération de registre. Avant de lire et d'écrire, nous devons d'abord ouvrir le descripteur correspondant. Par conséquent, nous introduisons d’abord les opérations de descripteur d’ouverture et de fermeture.
Description du paramètre : PIDescriptorHandle : Descripteur de poignée , nous l'utiliserons pour lire et écrire des données lors d'opérations ultérieures, similaires à la clé du registre. DescriptorKeyIDArray :
tableau uint32, qui stocke la collection de clés qui doit être interrogée. La définition associée est : orKeyIDArray[];
Les éléments du tableau sont les noms de clés dont vous avez besoin, c'est-à-dire les noms de paramètres que vous souhaitez interroger, c'est-à-dire quelles clés vous souhaitez interroger. Notez que comme il s'agit d'un type int32, chaque clé peut contenir un code ASCII représenté par 4 caractères. S'il fait moins de 4 octets, il peut être rempli d'espaces. Par exemple, la définition de cette affectation de paramètre peut définir {'Pam1', 'Pam2',NULL}, ce qui signifie que vous devez interroger deux paramètres, 'Pam1' et 'Pam2'. Par exemple, dans le système de script, la clé du filtre Flou gaussien (
GaussianBlur
) est 'GsnB'. Chaque valeur de clé est obtenue en appelant GetKeyProc() Chaque fois qu'une valeur est renvoyée, la clé correspondante dans ce tableau de chaînes sera définie comme vide ('.Cette fonction ferme un descripteur d'écriture et crée un nouveau handle de descripteur. Vous devez définir le nouveau descripteur sur PIDescriptorParameteres pour le renvoyer au programme hôte. Le comportement de la fonction ici est quelque peu similaire à celui de SelectObject dans les opérations GDI. Dans une opération GDI, lorsque vous définissez de nouvelles propriétés sur le contexte du périphérique, il vous renvoie les propriétés existantes, en attendant que vous fassiez une sauvegarde.
Je vais les expliquer un par un. Ici, je présente uniquement la forme générale et je les explique séparément si nécessaire. La plupart d'entre elles ont des caractéristiques relativement standardisées (quelques fonctions ont des formes d'exception, que nous présenterons séparément plus tard), c'est-à-dire que la lecture commence par Get et l'écriture commence par Put. Le paramètre est le type correspondant de pointeur de données utilisé pour recevoir les résultats de la requête (ou pour stocker les données écrites). Supposons que le type de données que nous devons interroger est TypeName, alors il se présente comme suit : 🎜>TypeName *
dest); //Read
OSErr (*
Put);
TypeNameProc) (descripteur PIWriteDescriptor, DescriptorKeyID, TypeName *dest); >DescriptorKeyID ,
TypeName *dest); h): Lire la sous-suite du descripteur Mise en évidence du code produite par Actipro CodeHighlighter (freeware)http:// www.php.cn/
-->//Lire l'ensemble de sous-fonctions membres
//写子函数集成员,形式类似前面的函数,但都额外需要提供key
typedef struct WriteDescriptorProcs
{
int16 writeDescriptorProcsVersion;
int16 numWriteDescriptorProcs;
OpenWriteDescriptorProc openWriteDe scriptorProc;
CloseWriteDescriptorProc closeWriteDescriptorProc;
PutIntegerProc putIntegerProc;
PutFloatProc putFloatProc;
PutUnitFloatProc putUnitFloatProc;
PutBooleanProc putBooleanProc;
PutTextProc putTextProc;
PutAliasProc putAliasProc;
PutEnumeratedProc putEnumeratedProc;
PutClassProc putClassProc;
PutSimpleReferenceProc putSimpleReferenceProc;
PutObjectProc putObjectProc;
PutCountProc putCountProc;
PutStringProc putStringProc ;
/* Les classes portées ne ne ne pas être utilisées par les plug-ins dans Photoshop 4.0 */
PutScopedClassProc putScopedClassProc;
PutScopedObjectProc putScopedObjectProc ;
} WriteDescriptorProcs;
Exemple de lecture et d'écriture de paramètres :
Lecture de paramètres depuis le système de script : Supposons que la clé de notre paramètre soit 'Pam1', nous utilisons une variable temporaire param1 pour la recevoir :
Lire un code de démonstration de paramètre
Jeton PIReadDescriptor = NULL //Opérateur de lecture
Clé DescriptorKeyID = NULL //uint32, c'est-à-dire char*, Nom de la clé
Type descripteurTypeID = NULL // descripteur Type
int32 flags = 0 >// Identification Tableau DescriptorKeyIDArray
= { 'Pam1', NULL }; //L'ensemble de clés à interroger
double param1; //Le paramètre que nous voulons lire //
Obtenir la structure des paramètres du descripteur PIDescriptorParameters
* descParams = gFilterRecord->descriptorParameters; NULL)
return euh ; //Obtenez la sous-fonction "lire" dans Descriptor Suite Set ReadDescriptorProcs
* readProcs =
gFilterRecord->descriptorParameters->readDescriptorProcs; 🎜>== NULL) return err; if (descParams->descripteur != NULL)
{
//Ouvrir le descripteur "lire"
jeton = readProcs->openReadDescriptorProc(descParams->descripteur, tableau);
si (jeton != NULL)
pendant
(readProcs->getKeyProc(token, &clé, &type, &drapeaux) && !err) 🎜> /Lisez nos paramètres
>getFloatProc(token, &
param1); >par défaut : 🎜>pause; } } }//Fermer le descripteur de lecture
err = readProcs->closeReadDescriptorProc(token);
//释放描述符
gFilterRecord->handleProcs- >disposeProc(descParams->descripteur);
descParams->descripteur = NULL;
}
}
Écrire les paramètres dans le système de script : Identique à l'exemple ci-dessus :
Écrire le code de démonstration du descripteur
OSErr err = noErr;
Jeton PIWriteDescriptor = NULL;
PIDescriptorHandle h;
const double param1 = 1.05;
PIDescriptorParameters* descParams = gFilterRecord -> >return
err; WriteDescriptorProcs* writeProcs = gFilterRecord->
descriptorParameters->writeDescriptorProcs; 🎜>== NULL) return err; token =
writeProcs-> openWriteDescriptorProc(); if (jeton !=
NULL) { //Écrire les paramètres ~ writeProcs->putFloatProc(token,'Pam1',
¶m1); //Descripteur de version gFilterRecord->
handleProcs
->disposeProc(descParams ->descripteur); //Ferme le descripteur "lire"
writeProcs->
closeWriteDescriptorProc( token, &h); //Renvoyer le nouveau descripteur à Photoshop descParams->descripteur
=
h; }
3.3 Suite DescriptorRegistry : (ensemble de fonctions d'enregistrement de descripteurs)
L'ensemble de fonctions d'enregistrement de descripteurs est principalement utilisé pour l'enregistrement et l'acquisition de descripteurs. Cela permet de confier à ps la sauvegarde de nos paramètres pendant que le filtre est appelé plusieurs fois. Il contient plusieurs fonctions clés pour l'enregistrement, la suppression et l'acquisition de clés.
Register()
Description : Enregistrez une clé.
Définition :
OSErr (*Register) (
/* IN */ const char* key, // Chaîne ou ID unique
/* IN */ PIActionDescriptor Descriptor, // Description Poignée professorale
/ * in */Boolean Ispersistent // S'il faut confier la maintenance PS pour stocker et restaurer
Effacer ()
Description : Supprimer une clé
Définition : OSErr (*Erase)
(
/* IN */ const char* key // Chaîne ou ID unique
);
Description : renvoie une clé. Le descripteur renvoyé est une copie, vous devez donc le publier activement après utilisation.
Définition :
OSErr (*Get) (
/* IN */ const char* key, // Chaîne ou ID unique 🎜> / Relâchez-le après utilisation );
3.4 Suite ActionDescriptor : (ensemble de fonctions de descripteur d'action)
Ensemble de fonctions de descripteur d'action, est utilisé pour stocker des clés (ou objets) en descripteurs, lisez-les à partir des descripteurs et autre gestion des descripteurs. Cet ensemble de fonctions contient à la fois des fonctions de lecture et d'écriture, et la méthode d'utilisation est similaire au descripteur de la section précédente. Il est défini comme suit :
PSActionDescriptorProcs Struct
Mise en évidence de code produite par Actipro CodeHighlighter (freeware)http:/ / www.php.cn/-->
typedef //Écrire les paramètres et s'inscrire
SPErr WriteRegistryParameters(void)
{
SPErr err = noErr;
//Obtenez SPBasicSuite, qui est la base pour obtenir d'autres suites
SPBasicSuite* basicSuite = gFilterRecord->sSPBasic;
// Pointeur de définition de fonction d'enregistrement de descripteur
PSDescriptorRegistryProcs* RegistryProcs = NULL;
//Pointeur de jeu de fonction de descripteur
PSActionDescriptorProcs* descriptorProcs = NULL;
Descripteur PIActionDescriptor = NULL;
//Nos paramètres
double param1
=0.1; //Obtenir la fonction d'enregistrement du descripteur définie
err = basicSuite
->AcquireSuite(kPSDescriptorRegistrySuite, ( const void
**)®istryProcs) ;//Obtenir l'ensemble de fonctions de descripteur d'action
err = basicSuite ->AcquireSuite(kPSActionDescriptorSuite,
(
const vide **)&descriptorProcs); 🎜>
=
descriptorProcs->Make(&descripteur); //Écrivez-nous les paramètres
err
= descripteurProcs->PutFloat(descripteur, 'Pam1 ',param1); //Enregistrer le descripteur de l'ID spécifié
err = RegistryProcs- >Register(plugInUniqueID, descriptor, true);
//
Descripteur de version
si (descripteur != NULL) descriptorProcs->
Gratuit (descripteur); //
Définir la fonction de libération
if (registryProcs != > 🎜> si ( descriptorProcs
!= NULL) basicSuite
->
ReleaseSuite(kPSActionDescriptorSuite, kPSActionDescriptorSuiteVersion);retour err;}
Exemple de lecture de nos paramètres :
Lecture des paramètres enregistrés
//Lire les paramètres enregistrés
SPErr ReadRegistryParameters(void)
{
SPErr err = noErr;
/ /Obtenez l'ensemble de fonctions de base, SPBasicSuite, grâce auquel vous pouvez obtenir d'autres ensembles de fonctions
SPBasicSuite* basicSuite = gFilterRecord->sSPBasic;
PSDescriptorRegistryProcs*registreProcs= NULL;
PSActionDescriptorProcs* descriptorProcs = NULL;
Descripteur PIActionDescriptor = NULL;
double param1;
//Obtenir la fonction d'enregistrement du descripteur
err = basicSuite-> const
void **)®istryProcs); //
Obtenir l'ensemble de fonctions du descripteur d'action err
= basicSuite->AcquireSuite(kPSActionDescriptorSuite , kPSActionDescriptorSuiteVersion, (const
void ** )& descripteurProcs);
//Obtenir le descripteur de l'ID spécifié
err = RegistryProcs->Get(plugInUniqueID, &descriptor);
//Lire les paramètres enregistrés
err = descriptorProcs->GetFloat(descriptor, ' Pam1',¶m1);
//Descripteur de version
if (descripteur != NULL )
descriptorProcs->Gratuit (descripteur);
//Ensemble de fonctions d'enregistrement du descripteur de version
if (registryProcs != NULL)
basicSuite->ReleaseSuite(kPSDescriptorRegistrySuite,
🎜>
Ensemble de fonctions de descripteur d'action de libération
if (descriptorProcs != NULL) basicSuite->
ReleaseSuite(kPSActionDescriptorSuite, euh ;}
Il est divisé en deux catégories principales, l'une est directement incluse dans la structure des paramètres du plug-in, appelée fonction de rappel direct ; l'autre est un fonction de rappel incluse dans l'ensemble des fonctions de rappel. Pour les fonctions de rappel direct, le texte explique uniquement que DisplayPixelsProc peut être utilisé pour mapper des images sur le DC de l'appareil. Y compris AdvanceStateProc, TestAbortProc et UpdateProgressProc mentionnés dans le premier article, ce sont tous des rappels directs et certaines fonctions de rappel direct appartiennent à une certaine suite. Pour l'ensemble de fonctions de rappel (Callback Suite), nous nous sommes ensuite concentrés sur la lecture, l'écriture, l'enregistrement et d'autres opérations dans la suite de descripteurs dans l'ensemble de fonctions de rappel. Cet ensemble de fonctions permet à PS d'enregistrer nos paramètres de filtre dans la séquence d'actions. , ou il peut enregistrer nos paramètres de filtre pour les enregistrer et les lire sur plusieurs appels. D'autres ensembles de fonctions de rappel tels que la gestion de la mémoire, les services d'espace colorimétrique et d'autres ensembles de fonctions n'ont pas encore été couverts en raison de limitations d'espace. (--Par hoodlum1980)
Pour plus d'introduction au développement de filtres Photoshop--Pour les articles liés aux fonctions de rappel de Photoshop, veuillez faire attention au site Web PHP chinois !