Maison interface Web Tutoriel PS Comment écrire un filtre Photoshop (1)

Comment écrire un filtre Photoshop (1)

Feb 22, 2017 am 09:49 AM

Il y a longtemps, j'ai écrit un article qui décrivait brièvement les concepts de base du développement de filtres dans Photoshop, décrivait la relation de collaboration entre les filtres et PS, et proposait également une démonstration du filtre à effet goutte de pluie. Mais le code source manque. Et nous allons nous demander comment programmer un filtre Photoshop à partir de zéro ? Comment pouvons-nous construire le cadre de base le plus simple du plug-in de filtre PS, puis continuer à ajouter les fonctions que nous souhaitons sur cette base ? Ici, je vais répondre à une question qui m'a été posée par un internaute à titre d'exemple, en partant du projet de construction le plus basique. Cet exemple (également le problème de cet internaute) est qu'il veut créer le filtre le plus simple, qui consiste simplement à remplir l'image de "rouge". Pour les utilisateurs de PS, c'est bien sûr une chose très simple et facile. Cela ne nécessite qu'une opération de touche de raccourci (les filtres sont généralement utilisés pour effectuer des tâches plus complexes). Nous partirons de cet exemple le plus basique pour expliquer comment écrire des filtres. processus. Un lien de téléchargement du code source pour l'exemple sera joint à la fin de l'article.

(1) L'outil de développement que nous utilisons est la version Visual Studio .NET 2005, avec Photoshop SDK CS (essentiellement le package de distribution composé de code C et de ressources). Les langages de développement utilisés sont C et C++.

Alors, est-il acceptable d'utiliser C# ou d'autres langages ? À l’heure actuelle, ce n’est pas réalisable. Par conséquent, pour développer des filtres Photoshop, les développeurs doivent avoir une bonne base en C et C, ce qui est le plus important. Bien sûr, il serait préférable que le développeur soit familiarisé avec le traitement d'images et ait des connaissances de base en traitement du signal numérique.

       

(2) Après avoir préparé les outils, nous ouvrons VS2005 et créons un nouveau projet. Nous choisissons Win32 de Visual C comme modèle de projet. Pour le nom du projet, nous saisissons le nom du filtre que nous voulons créer, comme le filtre "FillRed", ce qui signifie que ce filtre sert à remplir du rouge, comme indiqué ci-dessous :

Après avoir cliqué sur OK, dans la boîte de dialogue contextuelle des paramètres, cliquez sur « Paramètres de l'application », sélectionnez « DLL » dans le type d'application, puis cliquez sur OK.

Comment écrire un filtre Photoshop (1)                                                                                                                             Certains paramètres sont les suivants :

(a) En général, j'aime modifier le jeu de caractères utilisé par le projet pour "utiliser un jeu de caractères multi-octets", ce qui permet Nous devons utiliser char* et utiliser directement double Le type de chaîne de la citation. Bien entendu, Unicode peut également être utilisé, mais les fonctions de chaîne utilisées par les deux seront différentes. Vous pouvez le configurer comme vous le souhaitez.

Comment écrire un filtre Photoshop (1) (b) Le projet a été généré sous forme de DLL par défaut. Puisque l'extension du fichier de filtre de Photoshop est 8bf, nous définissons l'extension du fichier de sortie sur 8bf dans Linker->General. Modifiez-le comme indiqué ci-dessous.

                                                                                                                                                                                                                                                                Sélectionnez « Inclure les fichiers » : ajoutez plusieurs dossiers du SDK Photoshop au répertoire d'inclusion VC de l'option. Cela nous permettra de compiler plus facilement le projet sans signaler une erreur indiquant que le fichier est introuvable. Comme indiqué ci-dessous :

              Comment écrire un filtre Photoshop (1)

 

                                                                Le code de ce fichier source est remplacé comme suit :

// FillRed.cpp : 定义 DLL 应用程序的入口点。
//

#include "stdafx.h"
#include "PiFilter.h"
#include <stdio.h>

#ifdef _MANAGED
#pragma managed(push, off)
#endif


#ifndef DLLExport
#define DLLExport extern "C" __declspec(dllexport)
#endif

//=======================================
//        全局变量
//=======================================
//dll instance
HINSTANCE        dllInstance;
FilterRecord*    gFilterRecord;
int32*            gData;
int16*            gResult;
SPBasicSuite*    sSPBasic = NULL;
#define            TILESIZE    128 //贴片大小:128 * 128 
Rect            m_Tile;            //当前图像贴片(128*128)


//=======================================
//        函数列表
//=======================================
//辅助函数,拷贝矩形
void CopyPsRect(Rect* src, Rect* dest);
//辅助函数,把一个矩形置为空矩形
void ZeroPsRect(Rect* dest);
void DoParameters();
void DoPrepare();
void DoStart();
void DoContinue();
void DoFinish();


//辅助函数,拷贝矩形
void CopyPsRect(Rect* src, Rect* dest)
{
    dest->left = src->left;
    dest->top = src->top;
    dest->right = src->right;
    dest->bottom = src->bottom;
}

//辅助函数,把一个矩形置为空矩形
void ZeroPsRect(Rect* dest)
{
    dest->left = 0;
    dest->top = 0;
    dest->right = 0;
    dest->bottom = 0;
}

//DLLMain
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    dllInstance = static_cast<HINSTANCE>(hModule);
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

//===================================================================================================
//------------------------------------ 滤镜被ps调用的函数 -------------------------------------------
//===================================================================================================
DLLExport void PluginMain(const int16 selector,    void * filterRecord, int32 *data, int16 *result)
{
    gData = data;
    gResult = result;
    
    if (selector == filterSelectorAbout)
    {
        //显示关于对话框
        MessageBox(GetActiveWindow(), "FillRed Filter: 填充红色-- by hoodlum1980", "关于 FillRed", MB_OK);
    } 
    else 
    {
        gFilterRecord = (FilterRecordPtr)filterRecord;
        sSPBasic = gFilterRecord->sSPBasic;
    }

    switch (selector)
    {
        case filterSelectorAbout:
            //DoAbout();
            break;
        case filterSelectorParameters:
            DoParameters();
            break;
        case filterSelectorPrepare:
            DoPrepare();
            break;
        case filterSelectorStart:
            DoStart();
            break;
        case filterSelectorContinue:
            DoContinue();
            break;
        case filterSelectorFinish:
            DoFinish();
            break;
        default:
            *gResult = filterBadParameters;
            break;
    }
}

//这里准备参数,就这个滤镜例子来说,我们暂时不需要做任何事
void DoParameters()
{
}

//在此时告诉PS(宿主)滤镜需要的内存大小
void DoPrepare()
{
    if(gFilterRecord != NULL)
    {
        gFilterRecord->bufferSpace = 0;
        gFilterRecord->maxSpace = 0;
    }
}

//inRect     : 滤镜请求PS发送的矩形区域。
//outRect    : 滤镜通知PS接收的矩形区域。
//filterRect : PS通知滤镜需要处理的矩形区域。

//由于我们是使用固定的红色进行填充,实际上我们不需要请求PS发送数据
//所以这里可以把inRect设置为NULL,则PS不向滤镜传递数据。
void DoStart()
{
    if(gFilterRecord == NULL)
        return;

    //我们初始化第一个Tile,然后开始进行调用
    m_Tile.left = gFilterRecord->filterRect.left;
    m_Tile.top = gFilterRecord->filterRect.top;
    m_Tile.right = min(m_Tile.left + TILESIZE, gFilterRecord->filterRect.right);
    m_Tile.bottom = min(m_Tile.top + TILESIZE, gFilterRecord->filterRect.bottom);

    //设置inRect, outRect
    ZeroPsRect(&gFilterRecord->inRect); //我们不需要PS告诉我们原图上是什么颜色,因为我们只是填充
    CopyPsRect(&m_Tile, &gFilterRecord->outRect);

    //请求全部通道(则数据为interleave分布)
    gFilterRecord->inLoPlane = 0;
    gFilterRecord->inHiPlane = 0;
    gFilterRecord->outLoPlane = 0;
    gFilterRecord->outHiPlane = (gFilterRecord->planes -1);
}

//这里对当前贴片进行处理,注意如果用户按了Esc,下一次调用将是Finish
void DoContinue()
{
    if(gFilterRecord == NULL)
        return;

    //定位像素
    int planes = gFilterRecord->outHiPlane - gFilterRecord->outLoPlane + 1; //通道数量         
    uint8 *pData=(uint8*)gFilterRecord->outData;

    //扫描行宽度(字节)
    int stride = gFilterRecord->outRowBytes;

    //我们把输出矩形拷贝到 m_Tile
    CopyPsRect(&gFilterRecord->outRect, &m_Tile);
    for(int j = 0; j< (m_Tile.bottom - m_Tile.top); j++)
    {
        for(int i = 0; i< (m_Tile.right - m_Tile.left); i++)
        {
            //为了简单明了,我们默认把图像当作RGB格式(实际上不应这样做)
            //pData[ i*planes + j*stride + 0 ] = 0;    //Red  
            //pData[ i*planes + j*stride + 1 ] = 0;    //Green 
            pData[ i*planes + j*stride + 2 ] = 255;    //Blue
        }
    }

    //判断是否已经处理完毕
    if(m_Tile.right >= gFilterRecord->filterRect.right && m_Tile.bottom >= gFilterRecord->filterRect.bottom)
    {
        //处理结束
        ZeroPsRect(&gFilterRecord->inRect);
        ZeroPsRect(&gFilterRecord->outRect);
        ZeroPsRect(&gFilterRecord->maskRect);
        return;
    }
    //设置下一个tile
    if(m_Tile.right < gFilterRecord->filterRect.right)
    {
        //向右移动一格
        m_Tile.left = m_Tile.right;
        m_Tile.right = min(m_Tile.right + TILESIZE, gFilterRecord->filterRect.right);
        
    }
    else
    {
        //向下换行并回到行首处
        m_Tile.left = gFilterRecord->filterRect.left;
        m_Tile.right = min(m_Tile.left + TILESIZE, gFilterRecord->filterRect.right);
        m_Tile.top = m_Tile.bottom;
        m_Tile.bottom = min(m_Tile.bottom + TILESIZE, gFilterRecord->filterRect.bottom);
    }

    ZeroPsRect(&gFilterRecord->inRect);
    CopyPsRect(&m_Tile, &gFilterRecord->outRect);
    //请求全部通道(则数据为interleave分布)
    gFilterRecord->inLoPlane = 0;
    gFilterRecord->inHiPlane = 0;
    gFilterRecord->outLoPlane = 0;
    gFilterRecord->outHiPlane = (gFilterRecord->planes -1);
}

//处理结束,这里我们暂时什么也不需要做
void DoFinish()
{
}
Copier après la connexion


// FillRed.cpp : Définit le point d'entrée de l'application DLL.
//

#include
"stdafx.h"
#include
"PiFilter.h"
#include
< ;stdio.h>

#ifdef _MANAGED
#pragma géré(push, off)
#endif


#ifndef DLLExport
#define DLLExport extern "C" __declspec(dllexport)
#endif

//======================================== ==
// Variables globales
//============ === ========================
//instance dll
HINSTANCE dllInstance;
FilterRecord
* gFilterRecord;
int32
* gData;
int16
* gResult;
SPBasicSuite
* sSPBasic = NULL ;
#define TILESIZE 128 //Taille des tuiles : 128 * 128
Rect       m_Tile;     
//Tuile d'image actuelle (128*128) ======================= ===============


//
Liste des fonctions
//
========================== =============
/ /
Fonction auxiliaire, copier le rectangle
void CopyPsRect(Rect*
src, Rect* dest);//Fonction auxiliaire, définir un rectangle sur un rectangle vide
void ZeroPsRect(Rect *
dest);void DoParameters();
void
DoPrepare();
void
DoStart();
annuler
DoContinue();
void DoFinish();


//Fonction auxiliaire, copier le rectangle
void CopyPsRect(Rect* src, Rect* dest )
{
dest
->gauche =src->gauche;
dest
->haut =src->haut;
dest
->droite =src-> droite;
dest
->bas =src-> ;bas;
}

//Fonction auxiliaire, définir un rectangle sur un rectangle vide
void ZeroPsRect(Rect* dest)
{
dest
-> gauche = 0;
dest
-> haut = 0;
dest
-> droite = 0;
dest
->bas = 0;
}

//DLLMain
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
dllInstance
= static_cast<HINSTANCE>(hModule);
 
retour VRAI;
}

#ifdef _MANAGED
#pragma géré(pop)
#endif

//============= = ================================================== = ====================================
// ---------------------------------------- La fonction appelée par ps pour le filtre ---- -------------------------------------------- -
//==================================== == ================================================= == =============
DLLExport void PluginMain( const sélecteur int16, void * filterRecord, int32 *données, int16 *résultat)
{
gData
= données;
gRésultat
= résultat;

if (sélecteur == filterSelectorÀ propos )
{
                                                                                  >"
FillRed Filtre : Remplir rouge -- par hoodlum1980",
"À propos de FillRed", MB_OK);                                                                 🎜 > (FilterRecordPtr)filterRecord; sSPBasic = gFilterRecord->sSPBasic;
}
 commutateur
(sélecteur)
                                                                                   🎜>
//DoAbout();
                                                              >cas filterSelectorParameters : DoParameters();
pause

;
case filterSelectorPrepare: DoPrepare();

pause
; case
filterSelectorStar t:
DoStart() ; break;
 
case filterSelectorContinue : DoContinue();pause;
🎜>pause
;
par défaut
 : filterBadParameters; Préparez les paramètres ici. Pour cet exemple de filtre, nous n'avons encore rien à faire
void
DoParameters()
{ }//À ce moment, indiquez au PS (hôte) la taille de mémoire requise pour le filtre
void

DoPrepare()
{
 
if(gFilterRecord !=
NULL) { gFilterRecord
->

bufferSpace
= 0
;
gFilterRecord->
maxSpace
= 0; }
}
//inRect : Le filtre demande la zone rectangulaire envoyée par PS. //outRect : La zone rectangulaire reçue par la notification de filtre PS.
//
filterRect : La zone rectangulaire que le filtre de notification PS doit traiter. //Puisque nous remplissons avec une couleur rouge fixe, nous n'avons en fait pas besoin de demander à PS d'envoyer des données //
Donc ici, vous pouvez définir inRect sur NULL, alors PS ne transmettra pas les données au filtre.


void DoStart()
{
 if
(gFilterRecord
==NULL)

retour;
// Nous initialisons le premier Tile puis commençons à appeler
m_Tile.left =

gFilterRecord
- > filterRect.left; m_Tile.top =
gFilterRecord
->filterRect.top ;
m_Tile.right
= min(m_Tile.left
TILESIZE, gFilterRecord
-> filterRect.right);m_Tile.bottom = min(m_Tile.top TILESIZE, gFilterRecord->filterRect.bottom);

 
//Définir inRect, outRect
 ZeroPsRect( &gFilterRecord->inRect); //Nous n'avons pas besoin de PS pour dites-nous l'original Quelle est la couleur de l'image, car nous remplissons simplement
CopyPsRect(&m_Tile, &gFilterRecord->outRect);

 
//Demander tous les canaux (données pour la distribution entrelacée)
gFilterRecord->inLoPlane = 0;
gFilterRecord
->inHiPlane = 0;
gFilterRecord
->outLoPlane = 0 ;
gFilterRecord
->outHiPlane = (gFilterRecord-> ;avions -1);
}

//Le patch actuel est traité ici. Notez que si l'utilisateur appuie sur Echap, le prochain appel sera Terminer
void. DoContinue()
{
if(gFilterRecord == NULL)
retour;

 
//Pixel de positionnement
 int avions = gFilterRecord->outHiPlane - gFilterRecord ->outLoPlane 1 <🎜; >// Nombre de chaînes                                                                                                >(uint8*
)gFilterRecord
->outData; //Largeur de ligne de balayage (octets)
 int foulée = gFilterRecord->outRowBytes;

 
// Nous copions le rectangle de sortie dans m_Tile
CopyPsRect(&gFilterRecord-> outRect, &m_Tile);
🎜> j
= 0 ; j< (m_Tile.bottom - m_Tile.top) ; >) >(int i = 0

; je
< (m_Tile.right - m_Tile.left) <🎜); >) {                                                                                                             🎜>pData[ i*avions j*stride 0 ] = 0; //Rouge *avions j*stride 1 ] = 0; avions j*foulée

2
] = 255
>Bleu
} } }//
Déterminer si le traitement a été terminé     if(m_Tile.right >= gFilterRecord->filterRect.right && m_Tile.bottom >= gFilterRecord->filterRect.bottom)
    {
        
//处理结束
        ZeroPsRect(&gFilterRecord->inRect);
        ZeroPsRect(
&gFilterRecord->outRect);
        ZeroPsRect(
&gFilterRecord->maskRect);
        
return;
    }
    
//设置下一个tile
    if(m_Tile.right < gFilterRecord- >filterRect.right)
    {
        
//向右移动一格
        m_Tile.left = m_Tile.right;
        m_Tile.right 
= min(m_Tile.right   TILESIZE, gFilterRecord->filterRect.right);
        
    }
    
else
    {
        
//向下换行并回到行首处
m_Tile.left = gFilterRecord->filterRect.left;
        m_Tile.right 
= min(m_Tile.left   TILESIZE, gFilterRecord->filterRect.right);
        m_Tile. top 
= m_Tile.bottom;
        m_Tile.bottom 
= min(m_Tile.bottom   TILESIZE, gFilterRecord->filterRect.bottom);
    }

    ZeroPsRect(
&gFilterRecord->inRect);
CopyPsRect(
&m_Tile, &gFilterRecord->outRect);
 
//Demander tous les canaux (les données sont distribuées entrelacées)
 gFilterRecord-> ;inLoPlane = 0;
gFilterRecord
-> >inHiPlane = 0;
gFilterRecord
->outLoPlane = 0;
gFilterRecord
->outHiPlane = (gFilterRecord->avions -1 ; 🎜>void

DoFinish()
{
}
Le code ci-dessus est également un filtre À partir du framework de base, nous pouvons voir que l'une des fonctions d'exportation que fournira la DLL est la fonction PluginMain. Nous segmenterons l'image en tranches de 128*128 pixels, ce qui permet de transférer une plus petite quantité de données entre le PS et le. filtrer à chaque fois. Surtout pour les très grandes images, le traitement de découpage aidera à gérer les situations de mémoire restreinte, ce qui est également préconisé par Photoshop. Le processus d'appel consiste à initialiser la première tuile (Tile) dans l'appel de démarrage, puis nous définissons la première tuile sur outRect, ce qui signifie que nous demandons à PS de fournir un tampon pour recevoir le rectangle Les données traitées à l'emplacement. Quant à inRect, puisque nous ne faisons que remplir, nous ne nous soucions pas de la couleur d'origine de l'image, donc inRect peut être défini sur "rectangle vide". Canaux d'images Ici, par souci d'intuitivité et de simplicité du code, nous considérons uniquement les images RVB, c'est-à-dire les images à 3 canaux. Après avoir défini le premier outRect, PS commencera à appeler continue dans l'ordre, et les correctifs seront collés de gauche à droite et de haut en bas jusqu'à ce que tous les correctifs soient traités. Notez que inData et outData sont les données d'application et le "tampon de réécriture" fourni par PS au filtre. L'un est destiné à la lecture et l'autre à l'écriture. Leurs tailles sont contrôlées par les données renseignées lorsque le filtre informe PS de la demande. Le Temps Opérationnel ne doit jamais franchir ses limites.
                                                                                                                                                                                                                                Pointeur hors limite Cela fera planter le programme Photoshop !

Pour plus de détails sur le code principal de ce filtre, veuillez consulter les commentaires du code et l'explication dans mon article précédent. Et la documentation officielle du PS SDK. Nous ne détaillerons pas ici le principe du code, car il est très simple. Tous les codes ci-dessus doivent faire référence aux fichiers d'en-tête dans le SDK PS.

                                                                                      Mais la prochaine étape consiste à investir dans les ressources du PIPL.

Les ressources PIPL doivent être insérées dans le filtre afin d'être correctement reconnues et chargées par Photoshop. Selon la documentation fournie par PS, PIPL se prononce « pipple », ce qui signifie Plug-In Property List. Il s'agit d'une structure de données flexible et extensible utilisée pour représenter les métadonnées du module de plug-in (métadonnées). pipl inclut toutes les informations permettant à Photoshop de reconnaître et de charger les modules de plug-in, y compris certaines balises, ainsi que diverses propriétés statiques qui contrôlent chaque plug-in, etc. Votre filtre peut contenir une ou plusieurs structures "pipl".

Le processus d'insertion des ressources pipl pour les filtres est le suivant. Tout d'abord, nous devons ajouter un fichier *.r (fichier Macintosh Rez) au projet, puis utiliser cl.exe pour compiler ce fichier en un. Fichier *.rr. Enfin, utilisez CnvtPipl.Exe, un outil de conversion de ressources fourni par Ps SDK, pour convertir le fichier *.rr en fichier *.pipl, puis ajoutez un fichier de ressources *.rc pour le filtre et incluez le fichier *.rr. fichier pipl à la fin du fichier rc.

ps sdk nous a fourni un fichier r commun, comprenant des définitions d'attributs communs, qui est le fichier PIGeneral.r.

(a) Ensuite, nous ajouterons un fichier r au projet, cliquez avec le bouton droit sur le dossier "Resource Files" dans le gestionnaire de ressources, cliquez pour ajouter un nouveau fichier et entrez "FillRed.r" comme nom de fichier. Double-cliquez sur le fichier pour l'ouvrir et copiez le contenu suivant :

// ADOBE SYSTEMS INCORPORATED
// Copyright  1993 - 2002 Adobe Systems Incorporated
// All Rights Reserved
//
// NOTICE:  Adobe permits you to use, modify, and distribute this 
// file in accordance with the terms of the Adobe license agreement
// accompanying it.  If you have received this file from a source
// other than Adobe, then your use, modification, or distribution
// of it requires the prior written permission of Adobe.
//-------------------------------------------------------------------------------
#define plugInName            "FillRed Filter"
#define    plugInCopyrightYear "2009"
#define plugInDescription \
    "FillRed Filter.\n\t - http:\\www.cnblogs.com\hoodlum1980"

#include "E:\Codes\Adobe Photoshop CS2 SDK\samplecode\common\includes\PIDefines.h"

#ifdef __PIMac__
    #include "Types.r"
    #include "SysTypes.r"
    #include "PIGeneral.r"
    #include "PIUtilities.r"
    #include "DialogUtilities.r"
#elif defined(__PIWin__)
    #define Rez
    #include "PIGeneral.h"
    #include "E:\Codes\Adobe Photoshop CS2 SDK\samplecode\common\resources\PIUtilities.r"
    #include "E:\Codes\Adobe Photoshop CS2 SDK\samplecode\common\resources\WinDialogUtils.r"
#endif

resource &#39;PiPL&#39; ( 16000, "FillRed", purgeable )
{
    {
        Kind { Filter },
        Name { plugInName },
        Category { "Demo By hoodlum1980" },
        Version { (latestFilterVersion << 16) | latestFilterSubVersion },
        #ifdef __PIWin__
            CodeWin32X86 { "PluginMain" },
        #else
            CodeMachOPowerPC { 0, 0, "PluginMain" },
        #endif

        SupportedModes
        {
            noBitmap, doesSupportGrayScale,
            noIndexedColor, doesSupportRGBColor,
            doesSupportCMYKColor, doesSupportHSLColor,
            doesSupportHSBColor, doesSupportMultichannel,
            doesSupportDuotone, doesSupportLABColor
        },
            
        EnableInfo
        {
            "in (PSHOP_ImageMode, GrayScaleMode, RGBMode,"
            "CMYKMode, HSLMode, HSBMode, MultichannelMode,"
            "DuotoneMode, LabMode,"
            "Gray16Mode, RGB48Mode, CMYK64Mode, Lab48Mode)"
        },

        PlugInMaxSize { 2000000, 2000000 },

        FilterCaseInfo {
            {    /* array: 7 elements */
                /* Flat data, no selection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                /* Flat data with selection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                /* Floating selection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                /* Editable transparency, no selection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                /* Editable transparency, with selection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                /* Preserved transparency, no selection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                /* Preserved transparency, with selection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination
            }
        }
    }
};
Copier après la connexion


// ADOBE SYSTEMS INCORPORATED
// Copyright 1993 - 2002 Adobe Systems Incorporated
// All Rights Reserved
//
// NOTICE: Adobe permits you to use, modify, and distribute this
// file in accordance with the terms of the Adobe license agreement
// accompanying it. If you have received this file from a source
// other than Adobe, then your use, modification, or distribution
// of it requires the prior written permission of Adobe.
//-------------------------------------------------------------------------------
#define plugInName "FillRed Filter"
#define plugInCopyrightYear "2009"
#define plugInDescription \
"FillRed Filter.\n\t - http:\\www.cnblogs.com\hoodlum1980"

#include
"E:\Codes\Adobe Photoshop CS2 SDK\samplecode\common\includes\PIDefines.h"

#ifdef __PIMac__
#include
"Types.r"
#include
"SysTypes.r"
#include
"PIGeneral.r"
#include
"PIUtilities.r"
#include
"DialogUtilities.r"
#elif defined(__PIWin__)
#define Rez
#include
"PIGeneral.h"
#include
"E:\Codes\Adobe Photoshop CS2 SDK\samplecode\common\resources\PIUtilities.r"
    #include 
"E:CodesAdobe Photoshop CS2 SDKsamplecodecommonresourcesWinDialogUtils.r"
#endif

ressource 
'PiPL' ( 16000"FillRed", purgeable )
{
    {
         Genre { Filtre },
        Nom { plugInName },
        Catégorie { 
"Démo Par hoodlum1980" },
        Version { (lat estFilterVersion 
<< 16| latestFilterSubVersion },
        #ifdef __PIWin__
            CodeWin32X86 { 
"PluginMain" },
        
#else
            CodeMachOPorpPC { 
00"PluginMain" },
        
#endif

        Modes pris en charge
        {
            noB itmap, doesSupportGrayScale,
            noIndexedColor, doesSupportRGBColor,
            doesSupportCMYKColor, doesSupportHSLColor,
            doesSupportHSBColor, doesSupportMultichannel,
            doesSupportDu otone, doesSupportLABColor
        },
            
        EnableInfo
        {
             
"dans (PSHOP_ImageMode, GrayScaleMode, RGBMode,"
            
"CMYKMode, HSLMode, HSBMode , Mode Multicanal,"
            
"Mode Duotone, LabMode,"
            
"Gray16Mode, RGB48Mode, CMYK64Mode, Lab48Mode)"
        },

        PlugInMaxSize { 
20000002000000 },

        FilterCaseInfo {
             {    
/ * tableau : 7 éléments */
               
/* Données plates, pas de sélection  */
                inStraightData,
                outStraightData,
                 doNotWriteOutsideSelection,
                 doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                 
/* Données plates avec sélection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData ,
                copySourceToDestination,
                
/* Sélection flottante */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                 doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                 copySourceToDest ination,
                
/* Transparence modifiable, pas de sélection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNot FilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                
/* Transparence modifiable, avec sélection */
               inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination,
                
/* Transparence préservée, pas de sélection */
                inStraightData,
                outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                 copySourceToDestination,
                
/* Transparence préservée, avec sélection */
                inStraightData,
               outStraightData,
                doNotWriteOutsideSelection,
                doesNotFilterLayerMasks,
                doesNotWorkWithBlankData,
                copySourceToDestination
             >
         Faut可以看到我们定义了滤镜的名称,所在的滤镜分组名称(Catégorie),可以启用的图像模式等信息。然后右键点击该文件,在该文件的自定义生成规则的命令行中,点击编辑,输入以下内容:

                  


                 在“命令行”一栏点击编辑按钮,在弹出的窗口中输入以下两行:
cl /I E:CodesAdobe ~1samplecodeCommonIncludes /IE:CodesAdobe~1PhotoshopAPIPhotoshop /IE:CodesAdobe~1PhotoshopAPIPICA_SP /IE:CodesAdobe~1samplecodeCommonResources /EP /DWIN32=1 /Tc"$(InputPath)" > "$(ProjectDir)$(InputName).rr"

Cnvtpipl.exe "$(ProjectDir)$(InputName).rr" "$(ProjectDir)$(InputName).pipl"

 

            其中,第一行表示使用 CL.EXE 把该文件编译为 *.rr文件,上面的“/I”选项表示需要的包含目录。Comment écrire un filtre Photoshop (1)

第二行表示使用PS SDK中的 Cnvtpipl.exe 工具把 rr文件编译为 pipl文件,请注意为了简单,我把该工具复制到了项目的源文件所在文件夹下面。它位于SDK的路径是:“\samplecode\resources\cnvtpipl.exe”。

(b)下面我们为项目添加一个 rc文件,同样右键点击“资源文件”,添加一个FillRed.rc文件。

这是一个windows的资源文件,我们暂时还不需要任何资源,所以我们直接用文本方式打开IDE自动生成的RC文件,在结尾处添加下面的一行:

//

#endif    // APSTUDIO_INVOKED

#endif    // 英语(美国)资源
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// 从 TEXTINCLUDE 3 资源生成。
//
#include "FillRed.pipl"

/////////////////////////////////////////////////////////////////////////////
#endif    // 不是 APSTUDIO_INVOKED
Copier après la connexion


//

#endif    // APSTUDIO_INVOKED

#endif    // 英语(美国)资源
/////////////////////////////////////////////////////////////////////////////



#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// 从 TEXTINCLUDE 3 资源生成。
//
#include "FillRed.pipl"

/////////////////////////////////////////////////////////////////////////////
#endif    // 不是 APSTUDIO_INVOKED

 

            (5)我们编译项目,即可在项目的输出目录中看到 生成 FillRed.8bf 文件,下面我们把这个文件复制到 Photoshop的滤镜文件夹下面,例如我的Photoshop CS的滤镜所在目录是:“D:\Program Files\Adobe\Photoshop CS\增效工具\滤镜”

                  Comment écrire un filtre Photoshop (1)

 

            最后我们启动Photoshop,Photoshop会扫描插件目录,并把我们的滤镜加载到相应的菜单上,我们选择一个矩形选区,然后点击我们制作的滤镜相应菜单,即可看到效果,如下图所示。注意,下面的例子的效果是我仅仅把蓝通道填充了255。

                  Comment écrire un filtre Photoshop (1)

Dans le sous-menu du menu Aide de Photoshop - À propos des plug-ins -, vous pouvez voir l'élément "FillRed Filter..." que nous avons écrit. Lorsque vous cliquez dessus, PS lancera un appel à propos et vous verrez une fenêtre contextuelle. -up MessageBox.

                                                                                                                                                                                                                                 Par exemple, le répertoire du SDK Photoshop doit être ajusté en fonction de l'environnement spécifique. Les outils de conversion de ressources fournis par PS SDK sont également inclus dans le dossier du projet. (Remarque : la pièce jointe ne contient pas le SDK PS complet) http://files.cnblogs.com/hoodlum1980/FillRed.rar

Cette section décrit le mise en place d'un cadre de filtrage de base depuis la création du projet jusqu'à l'intégration des ressources pipl. Mais sa fonction est très basique et simple. À l'avenir, nous devrons peut-être continuer à enrichir cet exemple, notamment en introduisant des ressources de dialogue, en permettant à PS de mettre en cache et de lire nos paramètres pour notre filtre, y compris dans les graphiques d'aperçu du filtre de dessin de surface de dialogue et bientôt.

Pour plus d'articles sur la façon d'écrire un filtre Photoshop (1), veuillez faire attention au site Web PHP chinois !

Déclaration de ce site Web
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

Outils d'IA chauds

Undresser.AI Undress

Undresser.AI Undress

Application basée sur l'IA pour créer des photos de nu réalistes

AI Clothes Remover

AI Clothes Remover

Outil d'IA en ligne pour supprimer les vêtements des photos.

Undress AI Tool

Undress AI Tool

Images de déshabillage gratuites

Clothoff.io

Clothoff.io

Dissolvant de vêtements AI

AI Hentai Generator

AI Hentai Generator

Générez AI Hentai gratuitement.

Article chaud

R.E.P.O. Crystals d'énergie expliqués et ce qu'ils font (cristal jaune)
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Meilleurs paramètres graphiques
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌
Will R.E.P.O. Vous avez un jeu croisé?
1 Il y a quelques mois By 尊渡假赌尊渡假赌尊渡假赌

Outils chauds

Bloc-notes++7.3.1

Bloc-notes++7.3.1

Éditeur de code facile à utiliser et gratuit

SublimeText3 version chinoise

SublimeText3 version chinoise

Version chinoise, très simple à utiliser

Envoyer Studio 13.0.1

Envoyer Studio 13.0.1

Puissant environnement de développement intégré PHP

Dreamweaver CS6

Dreamweaver CS6

Outils de développement Web visuel

SublimeText3 version Mac

SublimeText3 version Mac

Logiciel d'édition de code au niveau de Dieu (SublimeText3)

Comment utiliser Photoshop pour créer des graphiques sur les réseaux sociaux? Comment utiliser Photoshop pour créer des graphiques sur les réseaux sociaux? Mar 18, 2025 pm 01:41 PM

L'article détaille à l'aide de Photoshop pour les graphiques des médias sociaux, couvrant la configuration, les outils de conception et les techniques d'optimisation. Il met l'accent sur l'efficacité et la qualité de la création graphique.

Comment préparer des images pour le Web à l'aide de Photoshop (optimiser la taille du fichier, la résolution)? Comment préparer des images pour le Web à l'aide de Photoshop (optimiser la taille du fichier, la résolution)? Mar 18, 2025 pm 01:35 PM

L'article discute de l'optimisation des images pour le Web à l'aide de Photoshop, en se concentrant sur la taille et la résolution des fichiers. Le principal problème est d'équilibrer la qualité et les temps de chargement.

Quelle est la raison pour laquelle PS continue de montrer le chargement? Quelle est la raison pour laquelle PS continue de montrer le chargement? Apr 06, 2025 pm 06:39 PM

Les problèmes de «chargement» PS sont causés par des problèmes d'accès aux ressources ou de traitement: la vitesse de lecture du disque dur est lente ou mauvaise: utilisez Crystaldiskinfo pour vérifier la santé du disque dur et remplacer le disque dur problématique. Mémoire insuffisante: améliorez la mémoire pour répondre aux besoins de PS pour les images à haute résolution et le traitement complexe de couche. Les pilotes de la carte graphique sont obsolètes ou corrompues: mettez à jour les pilotes pour optimiser la communication entre le PS et la carte graphique. Les chemins de fichier sont trop longs ou les noms de fichiers ont des caractères spéciaux: utilisez des chemins courts et évitez les caractères spéciaux. Problème du PS: réinstaller ou réparer le programme d'installation PS.

Quelles sont les questions courantes sur l'exportation du PDF sur PS Quelles sont les questions courantes sur l'exportation du PDF sur PS Apr 06, 2025 pm 04:51 PM

Questions et solutions fréquemment posées lors de l'exportation de PS en PDF: Problèmes d'intégration de la police: vérifiez l'option "Font", sélectionnez "intégrer" ou convertissez la police en courbe (chemin). Problème de déviation de couleur: convertir le fichier en mode CMYK et ajuster la couleur; L'exporter directement avec RVB nécessite une préparation psychologique pour l'aperçu et l'écart des couleurs. Problèmes de résolution et de taille des fichiers: choisissez la résolution en fonction des conditions réelles ou utilisez l'option de compression pour optimiser la taille du fichier. Problème d'effets spéciaux: fusionnez (aplatir) les couches avant de l'exportation, ou pesez les avantages et les inconvénients.

Comment préparer des images pour l'impression à l'aide de Photoshop (résolution, profils de couleurs)? Comment préparer des images pour l'impression à l'aide de Photoshop (résolution, profils de couleurs)? Mar 18, 2025 pm 01:36 PM

L'article guide la préparation d'images à l'impression dans Photoshop, en se concentrant sur la résolution, les profils de couleurs et la netteté. Il fait valoir que les profils de 300 PPI et CMYK sont essentiels pour les impressions de qualité.

Comment résoudre le problème du chargement lorsque PS montre toujours qu'il se charge? Comment résoudre le problème du chargement lorsque PS montre toujours qu'il se charge? Apr 06, 2025 pm 06:30 PM

La carte PS est "Chargement"? Les solutions comprennent: la vérification de la configuration de l'ordinateur (mémoire, disque dur, processeur), nettoyage de la fragmentation du disque dur, mise à jour du pilote de carte graphique, ajustement des paramètres PS, réinstaller PS et développer de bonnes habitudes de programmation.

Comment utiliser les capacités d'édition vidéo de Photoshop? Comment utiliser les capacités d'édition vidéo de Photoshop? Mar 18, 2025 pm 01:37 PM

L'article explique comment utiliser Photoshop pour l'édition vidéo, détaillant les étapes pour importer, modifier et exporter des vidéos et mettre en évidence les fonctionnalités clés telles que le panneau de chronologie, les couches vidéo et les effets.

Comment définir la protection des mots de passe pour l'exportation PDF sur PS Comment définir la protection des mots de passe pour l'exportation PDF sur PS Apr 06, 2025 pm 04:45 PM

Exporter PDF protégé par mot de passe dans Photoshop: ouvrez le fichier image. Cliquez sur "Fichier" & gt; "Export" & gt; "Exporter en PDF". Définissez l'option "Sécurité" et entrez le même mot de passe deux fois. Cliquez sur "Exporter" pour générer un fichier PDF.

See all articles