Maison  >  Article  >  interface Web  >  Une introduction au développement de plug-ins de filtres tiers pour Photoshop

Une introduction au développement de plug-ins de filtres tiers pour Photoshop

高洛峰
高洛峰original
2017-02-20 09:02:073207parcourir

Photoshop est un logiciel hors pair dans le domaine du traitement d'images numériques. Dans le même temps, il permet également à des tiers d’étendre ses fonctions sous forme de plug-ins. Les plug-ins Photoshop peuvent actuellement être divisés en neuf types suivants : automatisation (traitement par lots) (apparaît dans le sous-menu "Auto"), capture des couleurs, importation, exportation (apparaît sous le sous-menu "Importer", "Exporter"), extension, Filtres, Format de fichier (apparaît sous Ouvrir, Enregistrer sous), Analyse (avec fonction Exporter), Sélection (apparaît sous le menu « Sélectionner »). Nous prenons ici comme exemple le filtre le plus familier aux utilisateurs.
(1) Introduction à la partie générale du plug-in :
On devient l'hôte en appelant le programme principal du plug-in Dans la plupart des cas, il s'agit de Photoshop (ci-après dénommé PS). Un plug-in est en fait une bibliothèque de liens dynamiques sous le système Windows (avec une extension différente). PS utilise LoadLibray pour charger les modules plug-in. Lorsque l'utilisateur effectue l'action correspondante, cela provoquera une série d'appels PS au module plug-in. Tous ces appels appellent le même point d’entrée. Le point d'entrée est une telle fonction, définie comme suit : (Puisque PS est compatible avec Windows et Mac, nous donnons ici uniquement la définition sur le système Windows)

void ENTRYPOINT (
sélecteur court ,
void* pluginParamBlock,
long* pluginData,
short* result);

sélecteur :
Indicateur de type d'opération. Lorsque selector=0, cela a la même signification pour tous les types de plug-ins, c'est-à-dire demander d'afficher une boîte de dialogue À propos. D'autres valeurs ont des significations différentes selon le type de plug-in.

pluginParamBlock :
Il s'agit d'un pointeur vers une grande structure, qui est utilisée pour transmettre des informations et des données entre l'hôte et le plug-in. Il a différentes structures pour différents types de plugins.

pluginData :
Un pointeur vers le type int32. C'est une valeur que PS enregistre lors de plusieurs appels au plugin. L'une de ses utilisations standard est que le plug-in peut transmettre des pointeurs de données globales vers ce paramètre pour le stockage

result :
Un pointeur vers int16. Il doit définir le résultat à chaque fois que le plug-in est utilisé. est appelé. Le retour de 0 indique qu'aucune erreur ne s'est produite dans le code du plugin. Lorsqu'une erreur se produit, cette valeur renvoie un code d'erreur. Concernant les codes d'erreur, ps divise les plages de codes d'erreur pour différents types de plug-ins et prédéfinit certaines valeurs dans le SDK.

Boîte de dialogue À propos :
Tous les plugins doivent répondre aux appels à propos. Les plug-ins peuvent afficher une boîte de dialogue personnalisée. Cependant, afin de maintenir une cohérence, les conventions suivantes doivent être respectées :
(1) Affiché au centre horizontal de l'écran principal et à 1/3 de la hauteur verticalement.
(2) Il n'est pas nécessaire d'inclure un bouton OK, mais répondez aux clics à n'importe quel endroit et à la touche Entrée.

(2) Introduction au plug-in de filtre
La fonction du plug-in de filtre est de modifier la zone sélectionnée de l'image. Les comportements de filtrage vont du réglage de la saturation et de la luminosité au filtrage des images, etc. L'extension du filtre sous Windows est ".8BF".
La figure suivante montre la séquence d'appel entre les plug-ins PS et de filtre. Il s'agit d'une image dans la documentation du SDK. Il existe une telle image pour chaque type de plug-in. le filtre. La séquence d’appel du plug-in.
      Une introduction au développement de plug-ins de filtres tiers pour Photoshop

Les filtres peuvent être appelés à l'aide du menu des filtres, qui est le principal point de départ de l'appel. Après l'avoir appelé une fois, Photoshop placera la dernière opération de filtre dans le sous-menu "Dernier filtre" du menu des filtres. Cliquer sur ce menu à l'avenir correspondra à la "Commande de dernier filtre" dans l'image ci-dessus. Ci-dessous, nous présenterons brièvement le processus indiqué ci-dessus. Tout d’abord, regardons le « modèle » de la fonction de point d’entrée d’un filtre :

EntryPoint Of Plugin :PlugInMain
// Créer une définition pour les fonctions exportées
#define DLLExport extern " C" __declspec(dllexport)
#define SPAPI

DLLExport SPAPI 
void PluginMain(const int16 selector,
        
void * filterRecord,
        int32 
* data,
        int16 
* result)

 
commutateur (sélecteur)
 {
  
case filterSelectorÀ propos :
   
// DoAbout();
   pause;
  
cas filterSelectorParameters :
   DoParameters();
   
break;
  
case filterSelectorPrepare :
   DoPrepare();
   
break;
  
case filterSelectorStart:
   DoStart();
   
pause;
  
cas filterSelectorContinue :
   DoContinue();
   
pause ;
  
case filterSelectorFinish:
   DoFinish();
   
break;
  
par défaut :
   
*gResult = filterBadParameters;
   
pause;
 }
}

Notez que la fonction ci-dessus est la fonction la plus importante de notre filtre, car cette fonction est fournie pour les appels PS, nous pouvons voir que cette fonction est déclarée comme fonction d'export de Dll. Comme le montre la séquence d'appel, ce mécanisme rend le fonctionnement de cette fonction très similaire à la procédure de fenêtre de la fenêtre. La procédure de fenêtre est utilisée pour traiter les messages en fonction de l'ID MSG, et cette fonction est principalement utilisée pour effectuer les opérations correspondantes basées sur le sélecteur. Par conséquent, ils contiennent tous une structure de traitement de branche de type switch-case.

filterRecord
Le deuxième paramètre utilisé dans la fonction ci-dessus est un pointeur vers la structure AboutRecord lorsqu'elle est appelée (c'est-à-dire lorsqu'elle n'est pas appelée, c'est un pointeur vers le). Structure FilterRecord. La structure FilterRecord est une structure très vaste et complexe. C'est le support clé pour la communication et le transfert de données entre ps et les filtres. Sa taille = 452 octets contient environ plus de 100 membres, il y a un total de 7 pages. le document utilisé pour introduire le sens des membres de cette structure. La définition complète de FilterRecord se trouve dans le fichier d’en-tête : pifilter.h dans le SDK. Ci-dessous, j'expliquerai certains de ses membres les plus fondamentaux et les plus importants tels qu'ils sont mentionnés.

(3) Introduction au processus d'appel.

(3.1) appel filterSelectorParameters :
Si le filtre a certains paramètres qui doivent être définis par l'utilisateur, il doit alors enregistrer les paramètres dans un emplacement. Définissez ensuite l'adresse sur les données du troisième paramètre. PS initialisera ce paramètre à NULL. L'occurrence de cet appel dépend de la méthode d'appel de l'utilisateur. Lorsqu'un filtre vient d'être appelé, le filtre apparaîtra dans le menu de commandes le plus récent du filtre. L'utilisateur peut utiliser ce menu avec les mêmes paramètres (aucune boîte de dialogue ne s'affichera alors). il est temps de demander à l'utilisateur de définir de nouveaux paramètres) et d'appeler à nouveau. Cet appel ne se produit pas lorsque l'utilisateur l'appelle avec la dernière commande de filtre. (assister à la photo ci-dessus). Par conséquent, les paramètres doivent être vérifiés, vérifiés et initialisés à chaque fois si des paramètres incorrects peuvent créer un risque de plantage du programme.
Attention ! : Étant donné que les mêmes paramètres peuvent être utilisés pour des images de tailles différentes, les paramètres ne doivent pas dépendre de la taille de l'image. Par exemple, un paramètre ne doit pas dépendre de la largeur ou de la hauteur de l'image. Il est généralement plus approprié d'utiliser un pourcentage ou un facteur d'échelle comme paramètre.
Ainsi, votre bloc de données de paramètres doit contenir les informations suivantes :
1. Une signature afin que le filtre puisse rapidement confirmer qu'il s'agit bien de ses données de paramètres.
2. Un numéro de version afin que le plug-in puisse être mis à jour librement sans changer la signature.
3. Identification de l'ordre des octets. (À des fins multiplateformes) Indique quel endianisme est actuellement utilisé.

Bloc de paramètres (bloc de données de paramètres) et système de script (système de description de script)
Le système de script est utilisé pour mettre en cache nos paramètres et sera utilisé dans chaque type d'appel . Il est transmis au plugin afin que vous puissiez l'utiliser pour stocker tous vos paramètres. Une fois votre Bloc de paramètres validé, vous devez lire les données des paramètres passés puis mettre à jour vos paramètres. Par exemple :
1. Appelez d’abord ValidateMyParameters pour vérifier ou initialiser vos paramètres globaux.
2. Appelez ensuite la méthode ReadScriptingParameters pour lire les paramètres et les écrire dans votre structure de données de paramètres globaux.

(3.2) appel filterSelectorPrepare :
Cet appel permet à votre module plug-in d'ajuster l'algorithme d'allocation de mémoire de ps. La commande "Dernier filtre" démarrera à partir de cet appel. PS définit maxSpace (qui est membre de la structure FilterRecord (deuxième paramètre), les nouveaux membres qui apparaissent par la suite ne seront pas spécialement expliqués) au nombre maximum d'octets qu'il peut allouer au plug-in.
Membres imageSize, planes et filterRect :
Ces membres sont maintenant définis (en référence au SDK 6.0) et peuvent être utilisés pour calculer vos besoins en mémoire. imageSize, taille de l'image. avions, nombre de canaux.
filterRect : filtre rectangle.
Ici, je voudrais souligner à nouveau filterRect, qui est le type Rect défini par PS (similaire à la structure RECT de l'API Windows). Ce concept est également le concept de « rectangle englobant la sélection » mentionné et souligné à plusieurs reprises dans mon article de recherche sur les « Principes du filtre de déplacement ». À cette époque, je n'étais pas encore entré en contact avec le SDK PS. Ici, nous voyons que dans le code de Photoshop, cela s'appelle filterRect.
bufferSpace:
Si le filtre souhaite allouer plus de 32 Ko d'espace, ce membre doit être défini sur le nombre d'octets que vous souhaitez demander. ps essaiera de libérer un espace de cette taille avant le prochain appel (démarrer l'appel) pour garantir la réussite de votre prochain appel.

(3.3) Appel filterSelectorStart :
Dans cet appel, vous devez vérifier le bloc de données des paramètres, mettre à jour vos propres paramètres en fonction des paramètres transmis par ps et afficher votre interface utilisateur si nécessaire. Entrez ensuite dans votre processus de traitement de données.
rappel advanceState : (utilisé pour demander à PS de mettre à jour les données correspondantes)
Il s'agit d'une fonction de rappel très importante fournie par PS au filtre. Elle est définie comme suit :
#define MACPASCAL
<.> typedef short OSErr;
typedef MACPASCAL OSErr (*AdvanceStateProc) (void); Sa fonction est d'exiger que PS mette immédiatement à jour les données obsolètes dans FilterRecord. Par exemple, nous pouvons définir notre nouveau rectangle de traitement, puis appeler cette fonction, puis obtenir les nouvelles données dont nous avons besoin après cet appel. Si vous utilisez ce rappel, votre traitement principal peut être effectué lors de l'appel de démarrage sans utiliser d'appel continu. Une fois le traitement terminé, vous pouvez définir inRect=outRect=maskRect=NULL
Si vous n'utilisez pas ce rappel, vous devez définir la première zone rectangulaire, puis utiliser continue pour appeler le traitement en boucle.
Par exemple, nous pouvons utiliser la boucle suivante dans l'appel de démarrage pour traiter l'image jusqu'à ce que tout le traitement de l'image soit terminé.

Exemple de rappel advanceState

pour(..){
SetOutRect(out_recc);
gFilterRecord
->outLoPlane=0; gFilterRecord
->outHiPlane=(g_Planes-1);
 
//Demandez à PS de mettre à jour les données !
 *gResult = gFilterRecord- >advanceState(); 
if (*gResult ! =kNoErr)  
goto done;
 
//Traitement des données
. . . . . }

Inrect, Outress & Maskrect
Set inRect et Outress (Maskrect) est demandé pour demander la première zone de traitement. Si possible, vous devez couper l'image en morceaux plus petits pour réduire la quantité de mémoire requise lors de la transmission des données. Il est courant d'utiliser des correctifs 64x64 ou 128x128.

(3.4) appel filterSelectorContinue :
Lorsque l'un des inRect, outRect, maskRect n'est pas un rectangle vide, cet appel continuera à se produire.
inData, outData & maskData
Ces trois membres sont des pointeurs void *, pointant vers le point de départ des données d'image que vous avez demandées, notre travail principal est de calculer puis de définir les données ici lors de l'appel, inData et outData. sera rempli avec les données d'image à la position correspondante en fonction de la zone rectangulaire que vous avez demandée. Ensuite, votre tâche de traitement consiste principalement à modifier la zone de données outData et à indiquer à PS vos résultats de traitement, et PS mettra à jour les résultats dans l'image. Notez que vous n'avez pas besoin de prendre en compte la forme de sélection et de sélection transmise, car ce PS fonctionnel protégera automatiquement les données en dehors de la sélection, il vous suffit de faire attention à votre propre algorithme. Une fois le traitement terminé, définissez inRect et outRect pour le prochain traitement. Si c'est fini, laissez-les vides. Notez que inRect n'est pas nécessairement identique à outRect.
rappel progressProc : (utilisé pour définir la barre de progression PS)
Son type est défini comme :
typedef MACPASCAL void (*ProgressProc) (int32 done, int32 total);

Il s'agit de la fonction de rappel fournie par PS pour définir la barre de progression. Le plug-in peut utiliser ce rappel pour permettre à PS de mettre à jour la barre de progression ci-dessous. Il reçoit deux paramètres, l'un est le nombre de tâches terminées et l'autre est le total. nombre de tâches. Lorsque vous devez donner aux utilisateurs des commentaires sur la progression de votre traitement, vous pouvez définir la progression comme ceci :
gFilterRecord->progressProc ( progress_complete, progress_total );
rappel abortProc : (utilisé pour signaler) à L'hôte demande si l'utilisateur a effectué une action d'annulation)
Le type est défini comme :
typedef Boolean (*TestAbortProc) (void);
Ce rappel est utilisé pour demander si l'utilisateur a annulé le opération, qui prend beaucoup de temps. Lors du traitement, le plug-in doit appeler cette fonction plusieurs fois par seconde pour confirmer si l'utilisateur a annulé (par exemple en appuyant sur la touche Echap, etc.). Si TRUE est renvoyé, l'opération en cours doit être annulée et un code d'erreur positif renvoyé.


(3.5) appel filterSelectorFinish :

Cet appel permet au plug-in de nettoyer après traitement. finish sera appelé si et seulement si l’appel start réussit (aucune erreur n’est renvoyée). Même si une erreur se produit lors de la poursuite, l'appel de fin se produira toujours. Attention ! : Soyez prudent lors de l'annulation par l'utilisateur lors d'un appel continu, généralement lorsque vous attendez le prochain appel continu. Si l'utilisateur annule, l'appel suivant sera un appel de fin, pas de continuation ! ! ! .
Règles : si l'appel de démarrage réussit, Photoshop garantit qu'un appel de fin sera lancé.

(3.6) Codes d'erreur
Les plugins peuvent renvoyer des codes d'erreur standard du système d'exploitation ou signaler leurs propres erreurs (entiers positifs). Il est défini dans le SDK :

#define filterBadParameters –30100 // #define filterBadMode –30101 // Cette image de mode n'est pas supportée

(4) Filtre Raindrop DEMO
Plus tôt, nous avons principalement parlé des connaissances de base d'un filtre. Ensuite, cela n'extrait que les parties les plus importantes à expliquer, et des détails plus techniques ne peuvent pas être estimés en raison du manque d'espace. La base principale de ce qui précède est le document PS SDK6.0. Les règles principales appartiennent à la traduction du texte original, et une petite quantité de contenu appartient à ma pratique et à ma compréhension personnelles (j'utiliserai la couleur pour distinguer la compréhension personnelle). quand j'ai le temps).
Maintenant, nous commençons à expliquer la démo ! ! ! Vraiment fatigué. . . .
L'algorithme du filtre goutte de pluie fait principalement référence à un site Web étranger. C'est l'adresse que m'a signalée un internaute dans une réponse à un autre article. L'origine de ce filtre est l'algorithme de sphérisation (il existe ce filtre intégré dans PS). Nous ne présenterons pas l’algorithme car bien qu’il constitue le cœur du filtre, il n’est pas l’objet de cet article. Nous donnons le pseudo code de l'effet goutte d'eau basé sur ceci :

---Effet goutte d'eau----------------------------------
Au hasard générer un À la position cx,cy, un rayon R est généré aléatoirement,
                                                                                                                                                                                            En position cx, cy est généré aléatoirement avec un rayon R.
Ajoutez le reflet et l'ombre de la goutte d'eau à cet endroit.
Créez un modèle de flou gaussien 3*3 à l'intérieur de la gouttelette d'eau.
           ----------------------------------

(4.1) Positionnement des pixels
Répétez le processus ci-dessus pour produire plusieurs gouttelettes d'eau. C'est l'algorithme de base de ce filtre. La formule spécifique n'est pas donnée. Mais pour traiter les données, nous devons comprendre comment localiser une donnée de pixel dans les données transmises par PS. Par exemple, nous voulons obtenir les données de pixel du canal R à la position (x, y) sur l'image d'origine. . Comment pouvons-nous l'obtenir? Nous introduisons également ici les données importantes liées au positionnement des pixels dans FilterRecord. Elles sont de type int32 et appartiennent aux données fournies par PS au plug-in. Équivalent à BitmapData.Stride en c#. Mais veuillez noter que dans inData et outData, les données peuvent ne pas être alignées selon 4 octets ! Mais ps ne dit pas qu'il n'y a pas d'octets redondants à la fin de la ligne. En bref, c'est le nombre d'octets (span) occupés par une ligne de données d'image en mémoire.
int16 inLoPlane, inHiPlane, outLoPlane, outHiPlane,
Appartient aux données que le plug-in notifie à PS lors de la demande de PS. La valeur est la première valeur de canal et la dernière valeur de canal demandée dans le. prochain processus., notez que cette valeur est une valeur d’index avec 0 comme base. Par exemple, pour les images RVB, il y a trois canaux, 0 à 2 correspondant respectivement à B, V et R (notez que l'ordre dans le fichier est conservé ici, et non l'ordre RVB habituel dans PS !!!). Nous pouvons demander un canal à la fois ou plusieurs canaux à la fois, et les données de plusieurs canaux seront entrelacées en séquence. Par exemple, si nous définissons inLoPlane=0, inHiPlane=2, la disposition des données inData qui nous est fournie par PS est la suivante :
                                                                                            1. Les données inData qui nous sont fournies par PS sont : [G] [G] . ..
                                                         Localisez un pixel comme suit :
Tout d'abord, le nombre de canaux que nous demandons est défini sur planes : puis :
planes=inHiPlane-inLoPlane 1 //Number of; canaux
uint8 *pixels =(uint8*)inData;
Nous obtenons l'expression des données du canal avec l'indice k à la position (x, y) comme suit :
pixels [ y * inRowBytes x * planes k ]; > *(pixels y * inRowBytes x * plans k);
                                                                                                                                                                                                   Les données de pixels de la position y) sont les suivantes :

pixels [ y * inRowBytes x * 3 ]; y).p(x,y).G
pixels [ y * inRowBytes x * 3 2 ]; // p(x,y).R

D'accord, avec la base ci-dessus, nous pouvons examiner le traitement de modèle gaussien 3*3 suivant, Gaussian 3 * 3 Le modèle est le suivant :
1 2 1
2 4 2 /16
1 2 1
Nous utilisons la méthode de positionnement des pixels ci-dessus pour écrire facilement le contenu du traitement de boucle suivant :

Flou gaussien (modèle 3*3)
somme=0;
// Traitez chaque canal à tour de rôle
pour(k=0 ;kg_Planes;k )
{
 
// flouez-le !
sum =bufferPixels[(j-1)*rowBytes (i- 1)*g_Planes k];
somme
=bufferPixels[(j-1)*rowBytes (i)*g_Planes k]* 2;
somme
=bufferPixels[(j-1)*rowBytes (i 1 ) *g_Planes k];
sum
=bufferPixels[j *rowBytes (i-1)*g_Planes k]*2;
    somme
=bufferPixels[j*rowBytes i *g_Planes  k]*4;
    somme
=bufferPixels[j*rowBytes (i 1)*g_Planes  k]*2;
    sum
=bufferPixels[(j 1 )*rowBytes (i-1) *g_Planes  k];
    sum
=bufferPixels[(j 1)*rowBytes (i)*g_Planes  k]*2;
    somme
=bufferPixels[(j 1)*rowBytes (i 1)* g_Planes  k];
    somme
=somme>> 4;//即除以16
    pixels[j *rowBytes (i)*g_Planes  k ]=somme;
}


(5) Conclusion :
Enfin, jetons un coup d'œil à la capture d'écran de l'effet de l'utilisation du filtre : lorsque PS démarre, il analysera les plug-ins dans chaque répertoire de plug-ins et se chargera dans le menu correspondant.
Une introduction au développement de plug-ins de filtres tiers pour Photoshop
Résultats du traitement :
Une introduction au développement de plug-ins de filtres tiers pour Photoshop
Enfin, il existe un lien de téléchargement pour un package compressé de ce filtre :
RainDropFilter.rar
La méthode d'installation consiste à décompressez le fichier. , placez-le simplement dans le répertoire d'installation du filtre de Photoshop. Par exemple, pour Photoshop CS, son répertoire d'installation du filtre peut être sous la forme :
« C:Program FilesAdobePhotoshop CS Plug-in Filter »
À propos de PS Le SDK peut être obtenu sur le site officiel d'Adobe. Je ne sais pas s'il est actuellement gratuit. . . . .


(6) Références :
(1) Photoshop SDK 6.0.
(2) SDK Photoshop CS.
(3) (Algorithme de filtre Raindrop) Filtre : Gouttes de pluie : http://www.php.cn/

-------- -- ------------------------------------------------ -- ----------------
Annexe : Déclaration d'Adobe SDK !
-------------------------------------------------------------- --- -------------------
// ADOBE SYSTEMS INCORPORATED
// Copyright 1993 - 2002 Adobe Systems Incorporated
// Tous droits réservés
//
// ADOBE Systems Incorporated
// Copyright 1993 - 2002 Adobe Incorporated
// Tous droits réservés.
//
// AVIS : Adobe vous autorise à utiliser, modifier et distribuer ce
// fichier conformément aux termes du contrat de licence Adobe
// qui l'accompagne si vous l'avez. reçu ce fichier d'une source
// autre qu'Adobe, alors votre utilisation, modification ou distribution
// de celui-ci nécessite l'autorisation écrite préalable d'Adobe.
//
// Remarque : Adobe vous autorise à utiliser, modifier et distribuer ce fichier sous réserve des termes du contrat de licence Adobe applicable.
// Si vous avez obtenu ce fichier auprès d'une partie non-Adobe, votre utilisation, modification et distribution nécessitent un contrat de licence Adobe préalablement signé.
//--------------------------------------------- --------------------

Pour plus d'introduction et d'articles connexes sur le développement de plug-ins de filtres tiers pour Photoshop, veuillez faire attention au site Web PHP chinois !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn