在第一篇文章中我們建立了一個沒有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"
#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 */
/* Floating selection */
/* Editable transparency, no selection */
/* Editable transparency, with selection */
/* Preserved transparency, no selection */
/* Preserved transparency, with selection */
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,這樣我們在動作面闆看到的參數值就和濾鏡的對話框上的參數值是一緻的。否則我們看到的将是三個參數合成後的值。
最後,是濾鏡的源代碼下載下傳連結: