搜索
首页web前端PS教程对Photoshop第三方滤镜插件开发的简介

       Photoshop是数字图像处理领域内的杰出软件。同时,它也允许第三方以插件(Plugin) 的形式扩展其功能。Photoshop的插件目前一共可分为以下九种:自动化(批处理)(出现在‘自动’子菜单下),颜色拾取,导入,导出(出现在‘导入’‘导出’子菜单下),扩展,滤镜,文件格式(出现在打开,存储为),解析(与导出导出功能),选取(出现在‘选择’菜单下)。这里我们以最为用户熟悉的滤镜为例讲解。
(一)插件的通用部分介绍:
        调用插件的主程序我们成为宿主,在大多数情况下就是Photoshop(以下简称PS),一个插件实际上在windows系统下是一个动态链接库(只是具有不同扩展名)。PS使用LoadLibray加载插件模块。当用户采取相应操作时,将引起一系列ps对插件模块的调用。所有的这些调用都是调用同一个入口点。该入口点是这样一个函数,定义如下:(由于PS采取对windows和苹果机兼容,这里我们只给出在windows系统上的定义)

void ENTRYPOINT (
         short selector,
         void* pluginParamBlock,
         long* pluginData,
         short* result);

selector:
      操作类型指示符。当seletor=0时,它对所有类型的插件都具有相同的意义,即要求显示一个关于对话框。其他值,则根据插件类型而意义有所不同。

pluginParamBlock:
      这是一个指向一个很大结构的指针,这个结构用于在宿主和插件之间传递信息和数据。对于不同类型插件,它具有不同结构。

pluginData:
       一个指向int32类型的指针。它是为PS为插件在多次调用期间保存的一个值。它的一个标准用法是插件可把一些全局数据的指针交给该参数保存,

result:
       一个指向int16的指针,每次插件被调用它必须设置result。返回0表示插件代码中没有发生错误。当发生错误时,这个值返回一个错误码。有关错误码,ps为不同类型的插件分别划分了错误码的范围,并在SDK中预定义了一些值。

关于对话框:
所有插件应该响应about调用。插件可以显示一个自定义的对话框。但是为了保持一致性,应该遵守下面的约定:
(1)显示在主屏幕的水平居中,垂直1/3高度处。
(2)不需要包含一个OK按钮,而是响应在任意位置的点击以及回车键。

(二)滤镜插件的介绍
滤镜插件的作用是,针对图像的选择区域做出修改。滤镜行为从调节饱和度,亮度,到对图像的滤波等等。滤镜在windows下的扩展名是“.8BF”。
下图显示了PS和滤镜插件之间的调用序列,非常重要,这是在SDK文档中的一个图片,对每一个类型的插件都有这样一幅图,这里显示的是滤镜插件的调用序列。
               对Photoshop第三方滤镜插件开发的简介

滤镜可以使用滤镜菜单进行调用,即最上面的调用起始点。在调用一次以后,Photoshop将把最近一次滤镜操作放到滤镜菜单的“最近一次滤镜”子菜单上,以后点击该菜单则对应上图中的“最近一次滤镜命令”。下面我们将简要介绍上图流程。首先我们看一个滤镜的入口点函数的“模板”:

EntryPoint Of Plugin :PlugInMain
// Create a definition for exported functions
#define DLLExport extern "C" __declspec(dllexport)
#define SPAPI

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

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

注意,上面这个函数就是我们的滤镜的最重要的一个函数,因为这个函数是提供给PS调用的,我们可以看到这个函数声明为了一个Dll导出函数。从调用序列可以看到,这个机制使得这个函数的作用和 窗口的窗口过程 非常类似。窗口过程用于根据MSG ID处理消息,而这个函数主要用于根据selector做相应操作。因此他们都是有包含一个switch-case分支处理结构。

filterRecord
上面这个函数中用到的第二个参数,当属于about调用时(即selector=0)它是一个指向AboutRecord结构的指针,当非about调用时,他是一个指向FilterRecord结构的指针,FilterRecord结构是一个非常庞大复杂的结构,它是ps和滤镜之间用于沟通和传递数据的关键载体,它的sizeof=452个字节,大约包含100多个成员,在文档中一共有7页用于介绍该结构的成员含义。FilterRecord的完整定义位于头文件:sdk中的pifilter.h。下面我将在提到时再去讲解它最基本和最重要的一些成员。

(三)调用流程简介。

(3.1)filterSelectorParameters调用:
如果滤镜有一些参数需要用户设置,那么它应该把参数保存到一个位置。然后把该地址设置到第三个参数data。PS将把这个参数初始化为NULL。这个调用是否发生取决于用户的调用方式,当一个滤镜刚刚调用后,这个滤镜将出现在滤镜的最近一次命令菜单,用户可以以此菜单以相同参数(这时不会显示对话框要求用户设置新的参数)再次调用。当用户使用最后一次滤镜命令调用时,该调用不会发生。(参加上图)。因此,如果错误的参数可能产生使程序崩溃的危险时,应该每一次都检查,验证,然后初始化参数。
      注意!:因为对对不同大小的图像可以用同样的参数,所以参数不应该依赖图像大小。例如,某个参数不应该取决于图像宽度或者高度,通常应该用一个百分比或者比例系数作为参数比较合适。
      所以,你的参数数据块应该包含以下信息:
       1. 一个签名,这样滤镜可以快速的确认这是属于它的参数数据。
       2.一个版本号,这样插件可以自由升级而无需改变签名。
       3.字节序标识。(为了跨平台)指示当前使用的是什么字节序。

      Parameter block (参数数据块)和scripting system (脚本描述系统)
      脚本描述系统用于缓存我们的参数,在每种调用类型都会把它传递给插件,因此可以使用它存储你的所有参数。一旦你的Parameter block通过验证,你都应该从传递的参数读取数据,然后更新你的参数。例如:
       1.首先调用ValidateMyParameters验证或者初始化你的全局参数。
       2.然后调用ReadScriptingParameters方法读取参数,并写入你的全局参数数据结构。

(3.2)filterSelectorPrepare调用:
        该调用允许你的插件模块调节ps的内存分配算法。“最近一次滤镜”命令将从这个调用开始。PS将maxSpace(这是属于FilterRecord结构(第二个参数)的成员,此后出现的新成员将不再做特殊说明)设置为他能为插件分配的最大字节数。
         imageSize, planes 以及 filterRect 成员:
         这几个成员现在(指sdk 6.0)已经定义,可以用于计算你的内存需求量。imageSize,图像尺寸。planes,通道数。
         filterRect:滤镜矩形。
         这里我再强调一下这个filterRect,它是PS定义的Rect类型(和windows api的RECT结构类似)。这个概念也就是我在《置换滤镜原理》的研究一贴中提到的和反复强调的“选区外接矩形”的概念,在当时我还没有接触到ps sdk。这里我们看到,在Photoshop的代码中,它被称为filterRect。
         bufferSpace:
         如果滤镜想分配超过32K的空间,那么应该设置这个成员为你想申请的字节数。ps会尝试在下一个调用(start调用)前释放这样大小的空间,以保证你的下次调用成功。

(3.3)filterSelectorStart调用:
          该调用中,应该验证参数数据块,根据ps传递来的参数,去更新你自己参数,如果需要显示你的UI。然后进入你的数据处理流程。
          advanceState 回调:(用于请求PS更新相应的数据)
          这是一个PS提供给滤镜的非常重要的回调函数,它的定义如下:
           #define MACPASCAL
           typedef short OSErr;
           typedef MACPASCAL OSErr (*AdvanceStateProc) (void);
          他的作用是要求PS立即更新FilterRecord中的过时数据。例如我们可以设置我们新的处理矩形,然后调用该函数,就可以在此调用后得到我们需要的新的数据。如果你使用这个回调,那么你的核心处理可以全部在start调用中完成,而无需使用continue调用。当处理完成后,可以设inRect=outRect=maskRect=NULL.
如果你不使用这个回调,那么你应该设置第一个矩形区域,然后使用continue调用循环处理。
        例如我们可以在start调用是使用下面的循环来贴片处理图像,直到整个图像处理结束。

advanceState回调示例
for(..)
{
    SetOutRect(out_recc);
    gFilterRecord
->outLoPlane=0;
    gFilterRecord
->outHiPlane=(g_Planes-1);

        
//请求PS更新数据!
    *gResult = gFilterRecord->advanceState();
    
if (*gResult != kNoErr) 
        
goto done;

   
//处理数据
    。。。。。
}

          
         inRect, outRect & maskRect
         设置inRect 和 outRect (当使用选区蒙版时设置maskRect),以请求第一个处理区域。如果可能,你应该把图片切成小片,这样可以减少传递数据时的内存需求量。使用 64x64 或者128x128 的贴片是一个比较习惯性的做法。

(3.4)filterSelectorContinue调用:
        当inRect, outRect,  maskRect之中的任一个不是空矩形时,该调用会持续发生。
         inData, outData & maskData
         这三个成员都是void *指针,指向你请求的图像数据起始点,我们最主要的工作就是计算,然后设置这里的数据,在调用时,inData和outData会根据你请求的矩形区域被相应位置的图像数据填充,然后你的处理任务主要是修改outData数据区,告诉PS你的处理结果,PS会把结果更新到图像。注意,你不需要考虑传递进来的选区和选区形状,因为这个工作PS会自动保护选区外的数据,你只需要关注你自己的算法即可。处理结束后,设置下一次处理的inRect,outRect。如果结束了,那么把它们置空即可。注意,inRect不一定和outRect是一样的。
         progressProc 回调:(用于设置PS进度条)
         它的类型定义为: 
         typedef MACPASCAL void (*ProgressProc) (int32 done, int32 total);

         这是PS提供的用于设置进度条的回调函数,插件可以使用这个回调让PS更新下面的进度条,它接收两个参数,一个是已经完成的任务数,一个是总任务数。当你需要想用户反馈你的处理进度,则可以这样设置进度:
         gFilterRecord->progressProc ( progress_complete,   progress_total );

         abortProc 回调:(用于向宿主查询用户是否采取了取消行为)
         其类型定义为:
         typedef  Boolean (*TestAbortProc) (void);
         这个回调用于查询用户是否取消了操作,在一个消耗时间较长的处理中,插件应该每秒钟调用几次这个函数,确认用户是否做了取消(例如按下Esc键等)。如果返回TRUE说明当前的操作应该取消,并且返回一个正的错误码。
 

(3.5)filterSelectorFinish调用:
        该调用允许插件在处理结束后做清理工作。当并且仅当start调用成功(没有返回错误)时,finish才会被调用。即使continue中发生错误,finish调用依然会发生。
        注意!:小心处理用户在continue调用期间取消的行为,通常这时候你在期待下一次continue调用。如果用户取消,下一次调用将是finish调用,而不是continue!!!。
        规则:如果start调用成功,Photoshop保证将会发起Finish调用。

(3.6)错误码
        插件可以返回标准的操作系统错误码,或者报告它自己的错误(正整数)。在sdk中有定义:
       #define filterBadParameters –30100 // 
       #define filterBadMode –30101 // 不支持该模式图片

(四)雨滴滤镜的DEMO
         前面我们主要讲述了一个滤镜的基础知识。然后这还是仅仅提取了最重要的部分讲解的,更多的技术细节限于篇幅无法估计。上文的主要基础是PS SDK6.0的文档,其中的主要规则属于对原文的翻译,有少量内容属于我个人的实践和理解(我将在有时间的时候把属于个人理解的用颜色区分注明)。
         现在我们才开始进入demo的讲解!!!真的很累。。。。
         雨滴滤镜的算法主要参考了国外的一个网址,这是一个网友给我的另一篇文章的回复中报告给我的地址。这个滤镜的起源是球形化算法(在PS中有此内置滤镜)。算法我们不做介绍了,因为它虽然是滤镜的核心,但不是本文重点。我们给出在此基础上水滴效果的伪码:
      
          ---水滴效果--------------------
          随机产生一个位置cx,cy,随机产生一个半径R,
          在cx,cy处以R为半径做球形化扭曲。
          在该位置处加上水滴的高光和阴影。
          对水滴内部做一个3*3模板的高斯模糊。
         ----------------------------------

 (4.1)像素定位
         重复上述过程,将产生多个水滴。这就是这个滤镜的核心算法。具体公式不给出了。但是为了处理数据,我们必须了解如何在PS传递来的数据中定位一个像素数据,例如我们想获得原图上(x,y)位置上R通道的像素数据,我们如何拿到呢?这里还要介绍FilterRecord中和像素定位相关的重要数据成员,
         int32 inRowBytes ,outRowBytes, maskRowBytes,
         这是相应的inData,outData,maskData中的扫描行宽度,都是int32类型,属于PS提供给插件的数据。在c#中相当于BitmapData.Stride。但是注意的是,在inData和outData中,数据未必是按照4byte对齐的!但是ps也没有说行尾就没有任何冗余字节。总之,它是一行图像数据在内存中的占据的字节数量(跨度)。
          int16 inLoPlane, inHiPlane, outLoPlane, outHiPlane,
          属于插件像PS请求时通知给PS的数据,值得是下一个处理中请求的第一个通道和最后一个通道值,注意这个值是以0为base的索引值。例如对于RGB图像来讲,有三个通道,0到2分别对应B,G,R(注意这里保持文件中顺序,而不是PS中的习惯的RGB顺序!!!)。我们可以一次请求一个通道,也可以一次请求多个通道,多个通道的数据将会依次交叉排布(interleave)。例如,如果我们设置inLoPlane=0,inHiPlane=2,则PS提供给我们的inData数据排列是:
          [B G R] [B G R] ... ....
          如果我们把inLoPlane=inHiPlane=1,则PS提供给我们的inData是:
          [G] [G] ......
                   
          好了有了上面的几个关键成员讲解,我们可以看到我们如何定位一个像素,其方式如下:
         首先我们请求的通道数量设为planes:则:
          planes=inHiPlane-inLoPlane+1; //通道数量         
          uint8 *pixels=(uint8*)inData;
          我们取到(x,y)位置的索引为k的通道数据表达式如下:
          pixels [ y * inRowBytes + x * planes + k ];
          或者
          *(pixels + y * inRowBytes + x * planes + k);
          
          例如,我们请求了一副图片的RGB三个通道(inLoPlane=0,inHiPlane=2),为简便,inRect设置为整个图片大小,则位于(x,y)位置的像素数据如下: 

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

         好了,有了上面的基础,我们可以看下面的高斯3*3模板处理,高斯3*3模板如下:
         1 2 1
         2 4 2  /16
         1 2 1
         我们使用上面的像素定位方式,可以很容易写出下面的循环处理中的内容:

高斯模糊(3*3模板)
sum=0;
//依次处理每个通道
for(k=0;k<g_Planes;k++)
{
//blur it!
sum+=bufferPixels[(j-1)*rowBytes+(i-1)*g_Planes +k];
sum
+=bufferPixels[(j-1)*rowBytes+(i)*g_Planes +k]*2;
sum
+=bufferPixels[(j-1)*rowBytes+(i+1)*g_Planes +k];
sum
+=bufferPixels[j*rowBytes+(i-1)*g_Planes +k]*2;
sum
+=bufferPixels[j*rowBytes+i*g_Planes +k]*4;
sum
+=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;
sum
+=bufferPixels[(j+1)*rowBytes+(i+1)*g_Planes +k];
sum
=sum>>4;//即除以16
    pixels[j*rowBytes+(i)*g_Planes +k]=sum;
}


(五)结束语:
      最后,让我们看一下滤镜使用中的效果截图:在PS启动时,它将扫描各插件目录下的插件,并加载到相应菜单。
      对Photoshop第三方滤镜插件开发的简介
       处理结果:
        对Photoshop第三方滤镜插件开发的简介
       最后是这个滤镜的一个压缩包的下载链接:
       RainDropFilter.rar
       安装方法是,将文件解压,放到Photoshop的滤镜安装目录即可,例如对于Photoshop CS,它的滤镜安装目录可能形如:
       “C:\Program Files\Adobe\Photoshop CS\增效工具\滤镜\”
       有关PS SDK,可以从Adobe官方获取,目前是否是免费的我不清楚了。。。。。


(六)参考资料:
(1)Photoshop SDK 6.0。
(2)Photoshop SDK CS。
(3)(雨滴滤镜的算法)Filter: Raindrops :http://www.php.cn/

----------------------------------------------------------------------------
 附录:Adobe SDK的声明!
----------------------------------------------------------------------------
// ADOBE SYSTEMS INCORPORATED
// Copyright  1993 - 2002 Adobe Systems Incorporated
// All Rights Reserved
//
// ADOBE系统 公司
// 版权 1993 - 2002 Adobe公司
// 保留所有权利。
//
// 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.
//
// 注意:Adobe允许你在遵守相应Adobe许可协议条款的条件下,使用,修改,和分发这个文件。
// 如果你从非Adobe方获得该文件,则你使用,修改和分发需要此前签署的Adobe许可协议。
//-------------------------------------------------------------------------------

更多对Photoshop第三方滤镜插件开发的简介相关文章请关注PHP中文网!

声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
摄影师的Photoshop:增强和修饰图像摄影师的Photoshop:增强和修饰图像Apr 25, 2025 am 12:01 AM

在Photoshop中增强和修饰照片可以通过调整亮度和对比度、使用修复画笔工具来实现。1)调整亮度和对比度:通过Image->Adjustments->Brightness/Contrast菜单,增加亮度和对比度以改善曝光不足的照片。2)使用修复画笔工具:选择工具栏中的HealingBrushTool,涂抹以去除图像中的杂点或疤痕。

访问Photoshop:方法和可用性访问Photoshop:方法和可用性Apr 24, 2025 am 12:07 AM

可以通过购买永久许可证或订阅CreativeCloud两种方式获取Photoshop。1.购买永久许可证适合长期使用,无需每月支付,但无法享受最新更新。2.订阅CreativeCloud可访问最新版本及其他Adobe软件,需持续支付月费或年费。选择应基于使用频率和需求。

Photoshop最有用的是:常见任务和项目Photoshop最有用的是:常见任务和项目Apr 23, 2025 am 12:06 AM

Photoshop擅长图像编辑、图层和蒙版、数字绘画及多种设计应用。1)图像编辑与修复:去除瑕疵,调整色彩和亮度。2)图层与蒙版:非破坏性编辑和创作。3)数字绘画与插图:创作艺术作品。4)实际应用:平面设计、网页设计和数字艺术创作。

使用Photoshop:创意可能性和实际用途使用Photoshop:创意可能性和实际用途Apr 22, 2025 am 12:09 AM

Photoshop在实际应用中非常实用且具有创造性。1)它提供基本编辑、修复和合成功能,适合初学者和专业人士。2)高级功能如内容识别填充和图层样式可提升图像效果。3)掌握快捷键和优化图层结构能提高工作效率。

Photoshop:高级技术和工具Photoshop:高级技术和工具Apr 21, 2025 am 12:08 AM

AdobePhotoshop的高级功能包括高级选择工具、图层混合模式和动作与脚本。1)高级选择工具如快速选择工具和色彩范围选择工具可精确选择图像区域。2)图层混合模式如“叠加”模式能创造独特视觉效果。3)动作和脚本能自动化重复任务,提高工作效率。

Photoshop的主要功能:修饰和增强Photoshop的主要功能:修饰和增强Apr 20, 2025 am 12:07 AM

Photoshop在修图和增强方面的强大功能包括:1.使用“修复画笔工具”去除痘痘,2.使用“液化工具”瘦脸,3.使用“频率分离”技术进行精确修图,这些功能通过算法和图像处理技术实现,优化图像处理效果。

Photoshop的主要特征:深度潜水Photoshop的主要特征:深度潜水Apr 19, 2025 am 12:08 AM

Photoshop的关键功能包括图层与蒙版、调整工具、滤镜与效果。1.图层与蒙版允许独立编辑图像部分。2.调整工具如亮度/对比度可修改图像色调和亮度。3.滤镜与效果可快速添加视觉效果。掌握这些功能可以帮助创意专业人士实现创意愿景。

Photoshop和数字艺术:绘画,插图和合成Photoshop和数字艺术:绘画,插图和合成Apr 18, 2025 am 12:01 AM

Photoshop在数字艺术中的应用包括绘画、插图和图像合成。1)绘画:使用画笔、铅笔和混合工具,艺术家可创造逼真效果。2)插图:通过矢量和形状工具,艺术家可精确绘制复杂图形并添加效果。3)合成:利用蒙版和图层混合模式,艺术家可将不同图像元素无缝融合。

See all articles

热AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover

AI Clothes Remover

用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool

Undress AI Tool

免费脱衣服图片

Clothoff.io

Clothoff.io

AI脱衣机

Video Face Swap

Video Face Swap

使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热工具

PhpStorm Mac 版本

PhpStorm Mac 版本

最新(2018.2.1 )专业的PHP集成开发工具

记事本++7.3.1

记事本++7.3.1

好用且免费的代码编辑器

SublimeText3 Linux新版

SublimeText3 Linux新版

SublimeText3 Linux最新版

mPDF

mPDF

mPDF是一个PHP库,可以从UTF-8编码的HTML生成PDF文件。原作者Ian Back编写mPDF以从他的网站上“即时”输出PDF文件,并处理不同的语言。与原始脚本如HTML2FPDF相比,它的速度较慢,并且在使用Unicode字体时生成的文件较大,但支持CSS样式等,并进行了大量增强。支持几乎所有语言,包括RTL(阿拉伯语和希伯来语)和CJK(中日韩)。支持嵌套的块级元素(如P、DIV),

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

适用于 Eclipse 的 SAP NetWeaver 服务器适配器

将Eclipse与SAP NetWeaver应用服务器集成。