首頁 >web前端 >PS教程 >怎麼寫一個Photoshop濾鏡(1)

怎麼寫一個Photoshop濾鏡(1)

高洛峰
高洛峰原創
2017-02-22 09:49:302627瀏覽

            在很久前我曾經寫過一篇文章簡要講述了photoshop的濾鏡開發的基本概念,並描述了濾鏡和PS之間的協作關係,也提供了一個雨滴效果濾鏡的Demo。但是缺少原始碼。而且我們將要產生疑問,我們該如何從頭開始編寫一個Photoshop濾鏡?我們如何建立一個最簡單的Ps濾鏡插件的基本框架,然後在這個基礎上繼續添加我們想要的功能呢?這裡,我就以回答一個網友向我提出的問題為例,從最基本的建立專案開始講起。這個例子(也是這個網友的問題)是,他想做一個最簡單的濾鏡,也就是只把影像填滿為「紅色」。對於PS使用者來說,這當然是非常簡單容易的事情,只需要一個快捷鍵操作而已,(濾鏡通常是用來完成比較複雜的任務的),我們就從這個最基本的例子出發講解編寫濾鏡的過程。在文章最後將附上範例的原始碼下載連結。

            (1)我們使用的開發工具是Visual Studio .NET 2005版本,​​並搭配Photoshop SDK CS(本質上是一些C++程式碼和資源等檔案組成的發行包)。開發語言使用的是C和C++。

            那麼使用C#或其他語言使用嗎?目前來看可行性不大。所以要開發 Photoshop 濾鏡,則要求開發者必須有較好的C 和 C++ 基礎,這是最重要的。當然如果開發者熟悉影像處理,數位訊號處理的基本知識將會更好。

            (2)在準備工具後,並開啟VS2005,並新建專案。專案範本我們選擇 Visual C++ 的 Win32。專案名稱我們輸入我們想要建立的濾鏡名稱,例如「FillRed」濾鏡,表示這個濾鏡用於填紅色,如下圖:

                   點選確定以後,在彈出的設定對話框上,點擊“應用程式設定”,在應用程式類型中選擇選擇“DLL”,然後點擊確定。 怎麼寫一個Photoshop濾鏡(1)

                  

         名稱,在專案屬性中我們做以下設定:怎麼寫一個Photoshop濾鏡(1)

                  (以a)為常規中,我喜歡把項目使用的字元集改為“使用多位元組字元集”,這使我們可以用char*以及直接使用雙引號的字串類型。當然也可以使用Unicode,但兩者的使用的字串函數會有所不同。可以隨你的喜歡設定。                 ‧改為如下圖所示。

                  

         在右側下拉方塊中選取「包含檔案」:把幾個Photoshop SDK的資料夾加入選項的VC++包含目錄中,這將會方便我們編譯專案時不會報告找不到檔案的錯誤。如下圖所示:

                  怎麼寫一個Photoshop濾鏡(1)

 

      原始檔“FillRed.cpp”,我們把該原始檔的程式碼替換為如下:

// 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()
{
}


🠟//🠎 //

#include 
"
stdafx.h" #include 
stdio. h>#ifdef _MANAGED
#pragma managed(push, xport#define
 DLLExport extern "C " __declspec(dllexport)

#endif
//============================== ===========


//
        全域變數//=========================== =================
//dll instance

HINSTANCE      ;int32
*            gData ;int16
*            gResult;SPBasicSuite
* #define            TILESIZE    128 
*/? Rect            m_Tile;            
//
當前====28*1128))圖片 ============ ================
//        函數清單
//====================== =====================
//輔助函數,拷貝矩形void
 CopyPsRect(Rectvoid CopyPsRect(Rect , Rect* dest);
//
輔助函數,將一個長方形置為空矩形

est);
void  DoParameters();
void DoPrepare();
void DoStart();Do
void
 DoStart();void DoFinish();


//輔助函數,拷貝矩形 src, Rect
* dest) {    dest->left =
 src
->left; = src->top;    dest ->
right = src->right;    dest ->
bottom;}/ /輔助函數,把一個長方形置為空矩形
void
 ZeroPsRect(Rect* = 0
;
    dest
->top =
 
0. = 0

;
    dest-> bottom = 0
;
}//NLM+ hModule,                       DWORD  ul_reason_for_c  VOID lpReserved                     ){    
=
 static_castHINSTANCE>(hModule);  D
#pragma managed(pop) #endif

//
===================================== ================================================== ============//------------------------------- ----- 濾鏡被ps呼叫的函數 -------------------------------------- -----
//============================================ ================================================== =====
DLLExport void PluginMain(const int16selvo,  filterRecord, int32 *data, int16 * result){    gData = data;
    gResult 
if
 (selector ==
 filterSelectorAbout)    {      顯示關於對話框

        MessageBox(GetActiveWindow(), "FillRed "
關於 FillRed
", MB_OK) ;    }     
else
     {        gFilterRecord = (FilterRecordPtr)filterRecord;        sSPBasic = gFilterRecord->sSPBasic;    }

    
switch (selector )
    {
        
case filterSelectorAbout:
    
                 DoParameters();            break ;
        

case
 filterSelectorPrepare:       
break
;        case
 filterSelectorStart:     break;
        
case filterSelectorContinue :            DoContinue();break;
        
case filterSelectorFinish:
       
break;        
default:   
=
 filterBadParameters;             break;    }
}
//

這裡準備參數,就這個濾鏡例子來說,我們暫時不需要做任何事

//在此時告訴PS(宿主)濾鏡所需的記憶體大小
void
 DoP.

!=
 NULL )    {        gFilterRecord->
bufferSpace 
 terRecord->

maxSpace 
= 0;
    }
}
;    }};    //inRect     : 濾鏡請求PS發送的長方形區域。
//
outRect    : 濾鏡通知PS接收的長方形區域。 //filterRect : PS通知濾鏡需要處理的長方形區域。 //
由於我們是使用固定的紅色進行填充,實際上我們不需要請求PS發送資料


//
所以這裡可以把inRect設定為NULL,則PS不傳遞給濾鏡數據。
void DoStart()
{
    if🎠 

return
;    
//我們初始化第一個Tile ,然後開始進行呼叫
    m_Tile.left =
 gFilterRecord
-> gFilterRecord->p  gFilterRecord
->
filterRect.top; m_Tile.right 
=
 min(m_Tile.left + TILESIZE, gFilterRecord
->
 TILESIZE, gFilterRecord->.m_Tile.bottom 
= min(m_Tile.top + TILESIZE, gFilterRecord 設定inRect, outRect

    ZeroPsRect (&gFilterRecord
->inRect); //我們不需要PS告訴我們原圖上是什麼顏色,因為我們只是填充 & m_Tile, &gFilterRecord
->
outRect);;         gFilterRecord->inLoPlane  = 

0
;    gFilterRecord->
inHiPlane 
->inHiPlane  gFilterRecord->outLoPlane = 
0
;     gFilterRecord->outHiPlane = (gFilterRecord
->
 (gFilterRecord //這裡對目前貼片進行處理,注意如果使用者按了Esc,下次呼叫將是Finish
void DoContinue(){    if{    )         return;     
//

定位像素
    
int
. >outHiPlane 
-
 gFilterRecord->outLoPlane +
 
1

//
通道數          =
(uint8
*)gFilterRecord->outData; //掃描行寬度(位元組)
    int stride owBytes;    //我們把輸出矩形拷貝到 m_Tile

    CopyPsRect(&gFilterRecord
  
for(int j = 0
; j
 (m_Tile.bottom - m_Tile.top++     for(int i  = 0; i
 (m_Tile.right 
      {            //為了簡單明了,我們預設把影像當作RGB格式(實際上不應該這樣做)            //pData[ i*planes + j*stride Red              / /pData[ i*planes + j*stride + 1 ] = 0;    //Green  i*planes + j

*
stride +
 2 ] =
 
        }    }    //
    //完畢    if(m_Tile.right >= gFilterRecord-Tile.R >= gFilterRecord->filterRect. bottom)    {        //

處理結束
cord->
inRect);        ZeroPsRect(&gFilterRecord--&
gFilterRecord
-- outRect);        ZeroPsRect(&gFilterRecord
->    }    //設定下一個tile
    

if
     (m_Tile.right  gFilterRecord->filterRect.right)            m_Tile.left = m_Tile. right;
        m_Tile.right 
= min(m_Tile.right +
.)5,0,03LE-SI        
    }    else
    /
向下換行並回到行首處        m_Tile.left =fil.      m_Tile.right =

 min(m_Tile.left
+ TILESIZE, gFilterRecord
->
filterRect.right);             m_Tile.bottom = min(m_Tile.bottom 
+  TILESIZE, gFilterRecord->filterRect.bottom);    }    inRect);
CopyPsRect(
&m_Tile, &gFilterRecord->outRect);請全部要求
    gFilterRecord- >
inLoPlane 
= 0;    gFilterRecord->    gFilterRecord ;
    gFilterRecord
->outLoPlane =  0;
    gFilterRecord
->outHiPlane = (g );}
//處理結束,這裡我們暫時什麼也不需要做void DoFinish(){}   上面的程式碼也就是濾鏡的一個基本框架,我們可以看到DLL將提供的一個導出函數是PluginMain函數,我們將把圖像用128*128像素的切片進行分割處理,這可以使PS和濾鏡之間每次傳遞較少量數據,尤其是對很大的圖像來說,切片處理將有利於應對記憶體緊張的情況,也是Photoshop所提倡的,64*64或128*128是比較典型的尺寸。                 ¢後數據,至於inRect,由於我們僅僅是填充,所以我們不關心圖像的原來顏色如何,所以inRect 可以設定為「空矩形」。影像的通道這裡我們為了程式碼的直覺和簡單起見,我們就只考慮RGB影像,也就是有3個通道的影像。設定好第一個 outRect,然後PS就會依序不停的開始進行 continue 調用,貼片從左到右,從上到下的順序拼貼,直到貼片全部處理完成。注意inData 和outData 是PS 向濾鏡提供的申請資料和“回寫緩衝區”,一個用於讀取,一個用於寫,它們的大小是由濾鏡向PS通知請求時填寫的資料控制的,操作時絕不能越出其邊界。

            可能
                  有關此濾鏡主體程式碼詳細請參考程式碼註釋,以及我先前文章的解釋。以及PS SDK的官方文件。這裡我們就不再細述程式碼的原理了,因為它是恨簡單的。上面的一切程式碼裡面需要引用ps sdk中的頭檔。  
                  
(4)在此期間,以已成功完成專案以完成專案。但下面一步是欠入 PIPL 資源。

                  且可插入 PIPL 資源,以Photoshop正確辨識並負荷。根據PS提供的文件介紹,PIPL的發音讀作"pipple",它表示 Plug-In Property List。它是一個靈活,可擴展的用於表示插件模組元資料(metadata)的資料結構。 pipl包含了Photoshop識別和載入插件模組的所有訊息,包含一些標記,以及控制每個插件的各種靜態屬性等等,你的濾鏡可以包含一個或多個「pipl」結構。

                  為濾鏡插入pipl資源的過程如下,而首先我們需要為專案新增一個*.r(Macintosh的Rez檔案)文件,然後使用cl.exe 將這個檔案編譯為一個檔案最後用Ps SDK提供的一個資源轉換工具CnvtPipl.Exe 把*.rr 文件轉換為*.pipl 文件,然後為濾鏡添加一個*.rc資源文件,在rc文件的末尾把pipl文件包含進來即可。

                  ps sdk已經為我們提供了一個通用的 r文件,包括了一般的屬性定義,而它是 PIGeneral.r 檔。

                  (a)在「「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"
#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
            }
        }
    }
};


// 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資源 'PiPL'
 ( 

16000

"FillRed",可清除)
{
{        種類 { 過濾器 },        名稱 { plugInName },        類別 { "演示由hoodlum1980"  },
        版本 { (latestFilterVersion 
 16
 
16.
 latestFilterSubVersion },
        #ifdef __PIWin__           # CodeWin02#16 #        #else##            CodeMachOPowerPC { #0#0##" #"
PluginMain"
 },
        


endif



  
        {
            noBitmap,並支持GrayScale,
        是否支援CMYKColor, 是否支援HSLColor,
            是否為HSB顏色,且是否支援多重通道,##     支援雙色調,是否支援LABColor
        },                     "in (PSHOP_ImageMode, GrayScaleMode, RGBMode,
"
            " CMYK 模式、HSL 模式、HSB 模式、多通道模式、
#"
            "雙色調模式、LabMode、##"
#     #Gray16Mode、RGB48Mode、CMYK64Mode、Lab48Mode)" },

        PlugInMaxSize { 
20000002000000 },

       
/ * 數組:7 個元素 */                
/* 平面數據,無選擇  */                inStraightData,
                outStraightData,
                不寫入外部選擇,
                不過濾圖層蒙版,
                doesNotWorkWithBlankData,
                copySourceToDestination ,
                
/* 具備選擇的平面資料 # >             outStraightData,                doNotWriteOutsideSelection,                doesNotFilterLa yerMasks,                doesNotWorkWithBlankData ,                copySourceToDestination,
                

/*

 浮動選擇 

*/
#                in            riteOutsideSelection,                doesNotFilterLayerMas ks,             copySourceToDestination,                 #/*

##可編輯透明度,無選擇 

*/


                inStraightData,
              doNotWriteOutsideSelection,                                 copySourceToDestination,                /* 可編輯透明度,帶選擇區 */
#               ##                doNotWriteOutsideSelection ,
                    copySourceToDestination,
                

#/*

 保留透明度,且無選舉選舉選舉
##                in            ,                不過濾圖層蒙版,                copySourceToDestination,                






》 /* 保留透明度,選擇#*/

##o 和           doNotWriteOutsideSelection,
                且未過濾圖層蒙版,
                doesNotWorkWithBlankData,
                   }
    }
};






怎麼寫一個Photoshop濾鏡(1)


#####################################################################################################################################################################################' ######                 ‧文件的自訂產生規則的命令列中,點選編輯,輸入下列內容:######                  ##########   以下兩行:######cl /I E:\程式碼\Adobe~1\samplecode\Common\包含/IE:\Codes\Adobe~1\PhotoshopAPI\Photoshop /IE:\Codes\Adobe~1\PhotoshopAPI \PICA_SP /IE:\Codes\Adobe~1\samplecode\Common \資源 /EP /DWIN32=1 /Tc"$(InputPath)" > "$(ProjectDir)\$(InputName).rr"########Cnvtpipl.exe "$(ProjectDir)\$(InputName).rr" "$(ProjectDir)\$(InputName).pipl " ###### ######            其中,以第一行表示使用CL.EXE 將該檔案編譯為*.rr 文件,而上述的「/I」選項表示所需的包含目錄。

            第二行表示使用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


//

#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\增效工具\滤镜”

                  怎麼寫一個Photoshop濾鏡(1)

 

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

                  怎麼寫一個Photoshop濾鏡(1)

                  在Photoshop 的說明選單- 關於增效工具- 的子選單中,可看到我們所寫的「FillRed Filter ...」一項,點選它時PS即發起about 調用,即可看到彈出about 調用的MessageBox。

 

                  (6)最後,或有這個小例子的原始碼下載 - 例如PhotoshopSDK的目錄等,需要依據具體環境做出相對調整。 PS SDK提供的資源轉換工具也包含在專案資料夾內。 (註:附件中未包含完整PS SDK)

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

              

                  以在這一節中敘述了從專案創建,到嵌入pipl資源,並建立了一個基本的濾鏡架構。但它的功能是非常基本和簡單的,在以後的時間裡,我們可能需要繼續豐富這個例子,包括為它引入對話框資源,令PS為我們的濾鏡緩存和讀取我們的參數,包括在對話方塊表面繪製濾鏡的預覽圖形等等。

 

更多怎麼寫一個Photoshop濾鏡(1)相關文章請追蹤PHP中文網!

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn