怎样编写一个Photoshop滤镜(3)-- Scripting Plug-ins

            在第一篇文章中我们建立了一个没有UI的基本滤镜框架,并且引入PIPL资源使之能被PS加载到菜单。在第二篇文章中我们又引入了滤镜参数和相应的对话框资源,并且讲解了对话框在滤镜调用流程中的显示时机。这一篇文章我们将使滤镜支持动作记录和回放,也就是通过添加“术语资源”,使我们的滤镜参数被PS的脚本系统所获知(scripting-aware),并能够记录和回放。

            从Photoshop 4.0开始引入了一个新的面板以及相应的命令和回调函数:动作面板(浮动窗口),以及Descriptor 回调函数集。动作面板是Photoshop脚本系统用于和用户交互的接口,也是其核心所在。Photoshop 5.0扩展了动作结构,使自动化插件能够支持可描述的Photoshop命令。(《Photoshop API Guide》第11章)

            关于PS的 Scripting System,其来源是 PS 对苹果系统的事件和脚本机制的继承和支持,PS 的开发同时针对两种操作系统平台。这里我们介绍如何使我们的滤镜被PS脚本系统接纳。

 

            首先我们需要在 r文件中增加术语资源(terminology resource)。因此首先在 pipl 资源中增加一个 HasTerminology 结构,其定义如下:

 

//这个属性指明滤镜是否提供了 'aete'资源。
typedef struct HasTerminology
{
int32 classID; // classID from 'aete'
int32 eventID; // eventID from 'aete' or NULL if none
int16 aeteResNum; // number of 'aete' resource
CString uniqueID; // unique ID string (UUID or your own /). If present,
ignores AppleScript and keeps local to Photoshop.
} HasTerminology;

 

            这个结构将被增加到 r文件的 pipl资源内。下面我们在pipl资源后面添加了 aete 资源。

            在此前我们在一个通用的头文件中添加一些aete资源需要的定义:

Code_CommonDefine.h
//定义 Scripting Keys
#define KEY_FILLCOLOR        'fiCo'
#define KEY_OPACITY            'opcA'

#define plugInSuiteID        'filR'
#define plugInClassID        'filR'
#define    plugInEventID        'filR'
#define    plugInUniqueID        "18EC4E8F-DB34-4aff-AF99-77C8013BD74F"
#define plugInAETEComment    "FillRed example filter By hoodlum1980"
#define vendorName            "hoodlum1980"

 

            上面我们把我们的滤镜,滤镜的参数都定义为了键,关于键定义,需要符合以下原则:

            (a)它必须由4个字符组成。不够4个字符可以结尾用空格补足。

            (b)用户定义的键名应该以小写字母开头,同时至少含有一个大写字母。(因为全大写,全小写键名属于Apple定义)。

            滤镜的唯一标识符采用VC工具生成的GUID即可。

            

            然后我们对r文件增加aete 资源,aete 资源模板如下:

 

resource 'aete' (0)
{ // aete version and language specifiers
{ /* suite descriptor */
{ /* filter/selection/color picker descriptor */
{ /* any parameters */
/ * additional parameters */
}
},
{ /* import/export/format descriptors */
{ /* properties. First property defines inheritance. */
/* any properties */
},
{ /* elements. Not supported for plug-ins. */
},
/* class descriptions for other classes used as parameters or properties */
},
{ /* comparison ops. Not currently supported. */
},
{ /* any enumerations */
{
/* additional values for enumeration */
},
/* any additional enumerations */
/* variant types are a special enumeration: */
{
/* additional types for variant */
},
/* any additional variants */
/* class and reference types are a special enumeration: */
{
},
/* any additional class or reference types */
}
}
}

 

            请注意的是这是一个针对PS插件的aete资源模板,也就是说它不仅仅针对滤镜,也包括其他种类的PS插件。关于其具体含义这里我们不做详细讨论,可以参考相关PS SDK文档。

            【注意】即使有的节不需要,也必须提供一个空的花括号占位,而不能有缺失。 

            下面我们给出添加了aete资源后的 FillRed.r 文件,内容如下:

FillRed.r
// 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"
    #include "CommonDefine.h"        /* 包含了术语定义 */
#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"
    #include "CommonDefine.h"        /* 包含了术语定义 */
#endif

#include "PITerminology.h"
#include "PIActions.h"                /* 包含对 NO_REPLY 的定义 */

resource 'PiPL' ( 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
        },
        
        HasTerminology
        {
            plugInClassID,
            plugInEventID,
            16000,                /* int16 aeteResNum;  number of 'aete' resource */
            plugInUniqueID
        },
            
        EnableInfo
        {
            "in (PSHOP_ImageMode, RGBMode,"
            "CMYKMode, HSLMode, HSBMode, "
            "DuotoneMode, LabMode)"
        },

        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
            }
        }
    }
};

resource 'aete' (16000, "FillRed dictionary", purgeable)
{
    1, 0, english, roman,                                    /* aete version and language specifiers */
    {
        vendorName,                                            /* vendor suite name */
        "FillRed Demo By hoodlum1980",                        /* optional description */
        plugInSuiteID,                                        /* suite ID */
        1,                                                    /* suite code, must be 1 */
        1,                                                    /* suite level, must be 1 */
        {                                                    /* structure for filters */
            plugInName,                                        /* unique filter name */
            plugInAETEComment,                                /* optional description */
            plugInClassID,                                    /* class ID, must be unique or Suite ID */
            plugInEventID,                                    /* event ID, must be unique to class ID */
            
            NO_REPLY,                                        /* never a reply */
            IMAGE_DIRECT_PARAMETER,                            /* direct parameter, used by Photoshop */
            {                                                /* parameters here, if any */
                "FillColor",                                /* parameter name */
                KEY_FILLCOLOR,                                /* parameter key ID */
                typeInteger,                                /* parameter type ID */
                "Fill color in RGB",                        /* optional description */
                flagsSingleParameter,                        /* parameter flags */
                
                "Opacity",                                    /* optional parameter */
                KEY_OPACITY,                                /* key ID */
                typeInteger,                                /* type */
                "opacity in RGB",                            /* optional desc */
                flagsSingleParameter                        /* parameter flags */
            }
        },
        {                                                    /* non-filter plug-in class here */
        },
        {                                                    /* comparison ops (not supported) */
        },
        {                                                    /* any enumerations */
        }
    }
};

 

            在上面的文件中,我们可以看到我们的滤镜含有的两个主要参数:填充颜色 和 不透明度。位于 IMAGE_DIRECT_PARAMETER 结构中,typeInteger 指明它们是整数类型。flagsSingleParameter指明它们是基本类型(具有单一值)。此外,还可以把参数定义为枚举类型,同时把枚举的值域定义放在最后一节中,这里我们对此不做介绍了。

 

                  

                  滤镜被重新编译后,我们在PS中对它录制一个动作,命名为“测试 FillRed”,录制完成后,可以看到在动作面板上的左侧,出现了对话框选项的CheckBox,我们可以设置播放时是否弹出对话框。我们把FillRed滤镜命令的下拉列表展开可以看到滤镜参数:

                  FillColor: 10

                  Opacity:90

                  请注意参数的名字就是来自于上面的aete资源中的定义的滤镜参数名字属性,这就是我们需要给它定义一个可读的参数名的原因。需要注意的是,由于我们把对话框上三个参数合成为了一个参数,这就使得上面的参数显示是三个参数的合成值(10进制)。因此这里为了看清楚,我就只设置了 R 和 O1,其他参数都为0,这样我们在动作面板看到的参数值就和滤镜的对话框上的参数值是一致的。否则我们看到的将是三个参数合成后的值。

 

                  最后,是滤镜的源代码下载链接:

                  http://files.cnblogs.com/hoodlum1980/FillRed.rar

 

                  我的相关文章:

                  《怎样编写一个Photoshop滤镜(1)》

                  《怎样编写一个Photoshop滤镜(2)》

时间: 2024-09-06 13:30:22

怎样编写一个Photoshop滤镜(3)-- Scripting Plug-ins的相关文章

怎样编写一个Photoshop滤镜(4) -- 在对话框上增加缩略图

            在上一篇文章里,我们讲解了为滤镜添加术语资源,从而使我们的滤镜可以被PS的scripting system感知和描述,这样即友好支持了PS的"动作"面板.在这一篇文章中,我们将对此前的DEMO进行进一步的细化,例如在参数对话框上增加实时预览的小缩略图等.对话框的引入主要是给用户一个机会和接口,设置或调节滤镜使用的图像处理算法.通常作为UI的友好性,在对话框上应该提供预览图,这样可以直观的把参数对结果产生的影响反馈给用户,指导他们调整参数.而不是要用户必须反复执行

怎样编写一个Photoshop滤镜(2)

            在上一篇文章中,我们讲解了怎样创建一个Photoshop滤镜的项目,以及如何为滤镜嵌入PIPL资源使滤镜可以被PS识别和加载.并且我们已经建立了一个最简单最基本的滤镜框架.在这篇文章中,我们将细化滤镜和PS之间的调用流程,我们将为滤镜引入一个对话框资源,使用户可以对滤镜进行自定义参数的配置.并且我们将看到当用户从不同菜单位置发起滤镜调用时的流程区别,然后我们还将为我们的滤镜参数引入PS脚本描述系统的读写支持,将我们的参数存入PS的脚本系统中,并在以后的调用中读取出这些参数

怎样编写一个Photoshop滤镜(1)

            在很久前我曾经写过一篇文章简要讲述了 Photoshop 的滤镜开发的基本概念,并描述了滤镜和 PS之间的协作关系,也提供了一个雨滴效果滤镜的 Demo.但是缺少源代码.而且我们将要产生疑问,我们如何从头开始编写一个 Photoshop 滤镜呢?我们如何建立一个最简单的 PS 滤镜插件的基本框架,然后在这个基础上继续添加我们想要的功能呢?这里,我就以回答一个网友向我提出的问题为例,从最基本的建立项目开始讲起.这个例子(也是这个网友的问题)是,他想做一个最简单的滤镜,也就是

Photoshop滤镜巧绘五彩羽毛

滤镜 这个羽毛特效主要用了Photoshop滤镜中的风滤镜来表现羽毛边缘的效果,然后用图层模式做成五彩效果. 1. 在Photoshop中新建一个图像文件,色彩模式为RGB. 2.新建一层,选择套索工具绘制一个简单的羽毛形状,如图所示: 图片如下: 2.选择"Filter" > "Stylize" > "Wind"(滤镜-风格化-风),选择方向为 "from the right",如图所示. 3.复制羽毛层,选择&

用Photoshop滤镜轻松制作炫彩背景

滤镜 前面我们介绍过很多用Photoshop滤镜制作炫彩背景的实例,今天我们再来看一个简单几步实现绚丽纹理背景的实例. 完成效果如下: 新建图像800*800 背景为黑色,执行 Filter > Render > Lens Flare 连续N次的移动和添加光晕.效果如下 按CTRL+U执行 Hue/Saturation menu 设Saturation to -100如下 执行 Filter > Pixalate > Mezzotint 类型 = Medium Strokes. 再

Photoshop滤镜的选择技巧

技巧|滤镜 Photoshop的滤镜主要有五个方面的作用:优化印刷图象.优化WEB图象.提高工作效率.提供创意滤镜和创建三维效果.滤镜的出现,极大地增强了Photoshop 的功能,有了滤镜,我们就可以轻易地创造出十分"专业"的艺术效果.但Photoshop滤镜种类繁多,我们该如何选择实用的Photoshop 滤镜呢? 一.文字特效处理滤镜选择 用Photoshop制作的特效字不仅视觉效果一流,而且也非常实用.用Photoshop 的外挂滤镜来制作特效字就更简单了. 1.首选Ulead

Photoshop滤镜打造真实的火焰图

利用photoshop滤镜可轻松打造真实的火焰图片. 1.新建一个500X500,RGB模式,白色背景的图象,将前景色设置为黑色,填充背景层. 接着执行菜单-滤镜-渲染-镜头光晕,亮度为100,竟头类型选50-300毫米变焦,将光晕中心移至图象中心. 2.按CTRL+B将中间值的青色调节至-100兰色调至+100,再按CTRL+M将光晕边缘颜色调厚. 3.执行菜单-滤镜-扭曲-波浪,将生成趋数设置为6.波长最小值为60.最大值为100.波幅最小值为1.最大值为180.比例,水平垂直都为100%,

Photoshop滤镜优化处理照片

最近通过实验发觉有几个Photoshop滤镜对图像颜色的柔化和模糊对调整色彩有些帮助.下面我们一起来看看详细的优化处理步骤. 先打开一张图片,这张图片的色彩很灰暗,缺乏饱和度. 现在我们试图调整它的饱和度,但发觉图片质量不是太好. 建立调整图层,因为这样比直接在图片上修改要好一些. 调整如下,调整后发觉颜色出现一块一块的色斑,没有达到预期的效果,这是由于图片质量和PS的计算导致的. 为了让图像中尽量消除色块的现象,我们可以先对图片做一定的柔化或模糊的作用,使得每一个像素都和周围的像素能够尽量的融

Photoshop滤镜打造黑白城市艺术图片

  Photoshop滤镜打造黑白城市艺术图片           效果图虽然只用了简单的动感模糊滤镜,不过效果就非常有创意,建筑有一种动感效果,画面也简洁了很多.喜欢的同学可以去尝试一下.最终效果 原图 一.打开素材图片,把背景图层复制一层.选择菜单:滤镜 > 模糊 > 动感模糊,角度设置为90度,距离自定,确定后效果如下图. 二.加蒙版,用透明度较低柔边黑色画笔把底部区域擦出来,效果如下图. 三.把背景图层复制一层,按Ctrl + Shift + ] 置顶,然后选择菜单:滤镜 > 模