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

怎麼寫一個Photoshop濾鏡(1)

Feb 22, 2017 am 09:49 AM

            在很久前我曾經寫過一篇文章簡要講述了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_cast<HINSTANCE>(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

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

AI Hentai Generator

AI Hentai Generator

免費產生 AI 無盡。

熱門文章

R.E.P.O.能量晶體解釋及其做什麼(黃色晶體)
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.最佳圖形設置
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.如果您聽不到任何人,如何修復音頻
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O.聊天命令以及如何使用它們
1 個月前 By 尊渡假赌尊渡假赌尊渡假赌

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何使用Photoshop創建社交媒體圖形? 如何使用Photoshop創建社交媒體圖形? Mar 18, 2025 pm 01:41 PM

本文使用Photoshop詳細介紹了社交媒體圖形,涵蓋設置,設計工具和優化技術。它強調圖形創建的效率和質量。

如何使用Photoshop(優化文件大小,分辨率)準備Web圖像? 如何使用Photoshop(優化文件大小,分辨率)準備Web圖像? Mar 18, 2025 pm 01:35 PM

文章討論使用Photoshop優化Web的圖像,重點關注文件大小和分辨率。主要問題是平衡質量和加載時間。

PS一直顯示正在載入是什麼原因? PS一直顯示正在載入是什麼原因? Apr 06, 2025 pm 06:39 PM

PS“正在載入”問題是由資源訪問或處理問題引起的:硬盤讀取速度慢或有壞道:使用CrystalDiskInfo檢查硬盤健康狀況並更換有問題的硬盤。內存不足:升級內存以滿足PS對高分辨率圖片和復雜圖層處理的需求。顯卡驅動程序過時或損壞:更新驅動程序以優化PS和顯卡之間的通信。文件路徑過長或文件名有特殊字符:使用簡短的路徑和避免使用特殊字符。 PS自身問題:重新安裝或修復PS安裝程序。

PS導出PDF有哪些常見問題 PS導出PDF有哪些常見問題 Apr 06, 2025 pm 04:51 PM

導出PS為PDF時常見問題及解決方法:字體嵌入問題:勾選"字體"選項,選擇"嵌入",或將字體轉換成曲線(路徑)。顏色偏差問題:將文件轉換成CMYK模式,並進行校色;直接用RGB導出需做好預覽和顏色偏差的心理準備。分辨率和文件大小問題:根據實際情況選擇分辨率,或使用壓縮選項優化文件體積。特殊效果問題:導出前將圖層合併(扁平化),或權衡利弊。

如何使用Photoshop(分辨率,顏色配置文件)準備打印圖像? 如何使用Photoshop(分辨率,顏色配置文件)準備打印圖像? Mar 18, 2025 pm 01:36 PM

該文章指導在Photoshop中準備用於打印的圖像,重點介紹分辨率,色譜和清晰度。它認為300 ppi和CMYK配置文件對於質量印刷至關重要。

PS執行操作時一直顯示正在載入如何解決? PS執行操作時一直顯示正在載入如何解決? Apr 06, 2025 pm 06:30 PM

PS卡在“正在載入”?解決方法包括:檢查電腦配置(內存、硬盤、處理器)、清理硬盤碎片、更新顯卡驅動、調整PS設置、重新安裝PS,以及養成良好的編程習慣。

如何使用Photoshop的視頻編輯功能? 如何使用Photoshop的視頻編輯功能? Mar 18, 2025 pm 01:37 PM

本文介紹瞭如何使用Photoshop進行視頻編輯,詳細詳細介紹了導入,編輯和導出視頻的步驟,並突出了時間表面板,視頻層和效果等關鍵功能。

PS導出PDF如何設置密碼保護 PS導出PDF如何設置密碼保護 Apr 06, 2025 pm 04:45 PM

在 Photoshop 中導出帶密碼保護的 PDF:打開圖像文件。點擊“文件”&gt;“導出”&gt;“導出為 PDF”。設置“安全性”選項,兩次輸入相同的密碼。點擊“導出”生成 PDF 文件。

See all articles