웹 프론트엔드 PS 튜토리얼 포토샵 필터 작성 방법 (1)

포토샵 필터 작성 방법 (1)

Feb 22, 2017 am 09:49 AM

오래 전에 포토샵에서 필터 개발의 기본 개념을 간략하게 설명하고 필터와 PS의 협업 관계를 설명하고 빗방울 효과 필터의 데모를 제공하는 기사를 작성했습니다. 그런데 소스코드가 빠졌네요. 그리고 우리는 Photoshop 필터를 처음부터 어떻게 프로그래밍합니까? PS 필터 플러그인의 가장 간단한 기본 프레임워크를 어떻게 구축하고, 이를 기반으로 원하는 기능을 계속 추가하려면 어떻게 해야 할까요? 여기서는 한 네티즌이 나에게 던진 질문을 예로 들어 가장 기본적인 건설 프로젝트부터 답해보도록 하겠다. 이 예(또한 이 네티즌의 문제)는 그가 가장 간단한 필터를 만들고 싶어한다는 것입니다. 즉, 이미지를 "빨간색"으로 채우는 것입니다. PS 사용자의 경우 이는 매우 간단하고 쉬운 일입니다. 단축키 조작만 필요합니다. (필터는 일반적으로 더 복잡한 작업을 완료하는 데 사용됩니다.) 필터 작성 방법을 설명하기 위해 가장 기본적인 예부터 시작하겠습니다. 거울 과정. 예제의 소스 코드 다운로드 링크는 기사 끝에 첨부됩니다.

                                                                                                ~     (1) 우리가 사용하는 개발 도구는 Photoshop SDK CS(기본적으로 일부 C++ 코드와 리소스 및 기타 파일로 구성된 배포 패키지)와 쌍을 이루는 Visual Studio .NET 2005 버전입니다. 사용되는 개발 언어는 C와 C++입니다.

그럼 C#이나 다른 언어를 사용해도 괜찮을까요? 현재로서는 불가능할 것 같습니다. 따라서 포토샵 필터를 개발하려면 개발자에게 가장 중요한 C 및 C++에 대한 탄탄한 기초가 있어야 합니다. 물론 개발자가 영상 처리에 익숙하고 디지털 신호 처리에 대한 기본 지식이 있으면 더 좋겠죠.

       (2) 도구 준비가 끝나면 VS2005를 열고 새 프로젝트를 만듭니다. 프로젝트 템플릿으로 Visual C++의 Win32를 선택합니다. 프로젝트 이름에는 "FillRed" 필터와 같이 생성하려는 필터의 이름을 입력합니다. 이는 아래와 같이 이 필터가 빨간색을 채우는 데 사용된다는 의미입니다.

확인을 클릭한 후 팝업 설정 대화상자에서 "애플리케이션 설정"을 클릭하고 애플리케이션 유형에서 "DLL"을 선택한 후 확인을 클릭합니다. 포토샵 필터 작성 방법 (1)

                                                                                                                일부 설정은 다음과 같습니다.

(a) 일반적으로 프로젝트에서 사용하는 문자 집합을 "멀티바이트 문자 집합 사용"으로 변경하는 것을 좋아합니다. char*를 사용하고 double 인용문의 문자열 유형을 직접 사용합니다. 물론 유니코드도 사용할 수 있지만 둘이 사용하는 문자열 함수는 서로 다릅니다. 원하는대로 설정할 수 있습니다. 포토샵 필터 작성 방법 (1)

(b) 프로젝트는 기본적으로 DLL로 출력되어 있습니다. Photoshop의 필터 파일 확장자는 8bf이므로 링커->일반에서 출력 파일 확장자를 8bf로 설정했습니다. 아래 그림과 같이 변경합니다.

                                                                                                ~                            "파일 포함" 선택: 옵션의 VC++ 포함 디렉터리에 여러 Photoshop SDK 폴더를 추가하면 파일을 찾을 수 없다는 오류를 보고하지 않고 프로젝트를 더 쉽게 컴파일할 수 있습니다. 아래와 같이:

                                                                                              이 소스 파일의 코드는 다음과 같습니다. 다음과 같이 교체되었습니다: 포토샵 필터 작성 방법 (1)

// 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()
{
}
로그인 후 복사


// FillRed.cpp: DLL 애플리케이션의 진입점을 정의합니다.
//

#include
"stdafx.h"
#include
"PiFilter.h"
#include
< ;stdio.h>

#ifdef _MANAGED
#pragma 관리형(푸시, 꺼짐)
#endif


#ifndef DLLExport
#define DLLExport extern "C" __declspec(dllexport)
#endif

//======================================= ==
// 전역 변수
//============ ==== ========================
//dll 인스턴스
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();
무효
DoContinue();
void DoFinish();


//보조 기능, 직사각형 복사
void CopyPsRect(Rect* src, Rect* dest )
{
목적지
->왼쪽 = src->왼쪽;
목적지
->상단 = src->top;
dest
->right = src-> 오른쪽;
목적지
->하단 = src-> ;bottom;
}

//보조 기능, 직사각형을 빈 직사각형으로 설정
void ZeroPsRect(Rect* dest)
{
dest
-> 왼쪽 = 0;
목적지
-> 상위 = 0;
대상
-> 오른쪽 = 0;
목적지
->하단 = 0;
}

//DLLMain
BOOL APIENTRY DllMain( HMODULE hModule,
DWORD ul_reason_for_call,
LPVOID lpReserved
)
{
dllInstance
= static_cast<HINSTANCE>(hModule);
 
return TRUE;
}

#ifdef _MANAGED
#pragma 관리(팝)
#endif

//============= = ================================================ = ===================================
// --------------- ps가 호출하는 함수 필터 ---- ------------------------------- -
//=================================== == =============================================== == =============
DLLExport void PluginMain( const int16 선택기, void * filterRecord, int32 *data, int16 *결과)
{
gData
= data;
gResult
= 결과;

if (선택기 == filterSelectorAbout )
{
                                                                                       >"
FillRed 필터: 빨간색 채우기 -- by Hoodlum1980",
"FillRed 소개", MB_OK);                                                      🎜 > (FilterRecordPtr)filterRecord; sSPBasic = gFilterRecord->sSPBasic;
}
 스위치
(선택기)
                       >
//DoAbout();
                                                케이스 filterSelectorParameters: DoParameters();
break

;
case filterSelectorPrepare: DoPrepare();

break
; case
filterSelectorStart t:
DoStart() ; break;
 
case filterSelectorContinue: DoContinue();중단;
🎜>중단
;
기본값
: filterBadParameters; 여기서 매개변수를 준비합니다. 이 필터 예에서는 아직 아무것도 할 필요가 없습니다.
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)
반품
;
//
첫 번째 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);

 
//Set inRect, outRect
 ZeroPsRect(&gFilterRecord->inRect) //PS는 필요하지 않습니다. 원본 이미지에 어떤 색상이 있는지 알려주세요.
CopyPsRect(&m_Tile, & gFilterRecord->outRect);

데이터는 인터리브 배포)
gFilterRecord
->
inLoPlane = 0 ; gFilterRecord->
inHiPlane
= 0; gFilterRecord->
outLoPlane
= 0; gFilterRecord->
outHiPlane
= (gFilterRecord- >비행기 -1);}
//

현재 패치가 여기에서 처리됩니다. 사용자가 Esc를 누르면 다음 호출은 Finish
void
DoContinue( )
{<🎜입니다. >if
(gFilterRecord
== NULL)return;
 //
위치 픽셀
 int
평면 = gFilterRecord->outHiPlane - gFilterRecord-> outLoPlane + 1 //채널 수                                                                        (uint8*)gFilterRecord->
outData;//스캔 줄 너비(바이트)
 int stride = gFilterRecord->outRowBytes;

 
// 출력 직사각형을 m_Tile
CopyPsRect(&gFilterRecord->에 복사합니다. outRect, &m_Tile);
🎜> j
= 0 ; j< (m_Tile.bottom 🎜>- m_Tile.top); 🎜>) { for (int i =

0; i< (m_Tile.right - m_Tile.left); i++)                                                         ~ > = 0 //빨간색 pData[ i*planes + j*stride + 1 ] = 0; i*planes
+
j*
보폭
+ 2 ]
= 255 //
파랑
} }  //처리 완료 여부 판단    if(m_Tile.right >= gFilterRecord->filterRect.right && m_Tile.bottom >= gFilterRecord->filterRect.bottom)
    {
        
//处理结束
        ZeroPsRect(&gFilterRecord->inRect);
        ZeroPsRect(
&gFilterRecord->outRect);
        ZeroPsRect(
&gFilterRecord->maskRect);
        
반환;
    }
    
//设置下一个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);
 
//모든 채널 요청(데이터는 인터리브 분산됨)
 gFilterRecord-> ;inLoPlane = 0;
gFilterRecord
-> >inHiPlane = 0;
gFilterRecord
->outLoPlane = 0;
gFilterRecord
->outHiPlane = (gFilterRecord->비행기 -1 ; 🎜>void

DoFinish()
{
}
위 코드도 필터입니다. 기본 프레임워크에서 DLL이 제공하는 내보내기 기능 중 하나가 PluginMain 기능임을 알 수 있습니다. 이미지를 128*128 픽셀 슬라이스로 분할하여 PS와 DLL 간에 더 적은 양의 데이터를 전송할 수 있습니다. 특히 매우 큰 이미지의 경우 슬라이싱 처리는 Photoshop에서 권장하는 64*64 또는 128*128 크기를 처리하는 데 도움이 됩니다. 호출 프로세스는 시작 호출에서 첫 번째 타일(Tile)을 초기화한 다음 첫 번째 타일을 outRect로 설정하는 것입니다. 이는 PS에게 직사각형을 수신할 버퍼를 제공하도록 요청한다는 의미입니다. inRect의 경우 단지 채우는 중이므로 이미지의 원래 색상은 신경 쓰지 않으므로 inRect를 "빈 직사각형"으로 설정할 수 있습니다. 이미지 채널 여기서는 코드의 직관성과 단순성을 위해 RGB 이미지, 즉 3채널 이미지만을 고려합니다. 첫 번째 outRect를 설정한 후 PS는 continue 호출을 순서대로 시작하고 패치는 모든 패치가 처리될 때까지 왼쪽에서 오른쪽으로, 위에서 아래로 콜라주됩니다. inData 및 outData는 PS가 필터에 제공하는 애플리케이션 데이터이자 "쓰기 저장 버퍼"입니다. 하나는 읽기용이고 다른 하나는 필터가 PS에 요청을 알릴 때 채워지는 데이터에 의해 제어됩니다. 작동 시간은 경계를 넘어서는 안 됩니다.
                                                                                                ~         포인터가 범위를 벗어나면
Photoshop 프로그램이 중단됩니다!

이 필터의 주요 코드에 대한 자세한 내용은 이전 기사의 코드 주석과 설명을 참조하세요. 그리고 PS SDK의 공식 문서입니다. 코드의 원리는 매우 간단하므로 여기서는 자세히 설명하지 않겠습니다. 위의 모든 코드는 ps SDK의 헤더 파일을 참조해야 합니다.

                                                                           하지만 다음 단계는 PIPL 리소스에 투자하는 것입니다.

Photoshop에서 PIPL 리소스를 올바르게 인식하고 로드하려면 필터에 PIPL 리소스를 삽입해야 합니다. PS에서 제공한 문서에 따르면 PIPL의 발음은 플러그인 속성 목록을 의미하는 "pipple"입니다. 플러그인 모듈 메타데이터(메타데이터)를 나타내는 데 사용되는 유연하고 확장 가능한 데이터 구조입니다. pipl에는 일부 태그는 물론 각 플러그인을 제어하는 ​​다양한 정적 속성 등을 포함하여 Photoshop이 플러그인 모듈을 인식하고 로드하는 데 필요한 모든 정보가 포함되어 있습니다. 필터에는 하나 이상의 "pipl" 구조가 포함될 수 있습니다.

필터용 pipl 리소스를 삽입하는 과정은 다음과 같습니다. 먼저 프로젝트에 *.r(Macintosh Rez 파일) 파일을 추가한 후 cl.exe를 사용하여 이 파일을 *.rr 파일. 마지막으로 Ps SDK에서 제공하는 리소스 변환 도구인 CnvtPipl.Exe를 사용하여 *.rr 파일을 *.pipl 파일로 변환한 후 필터용 *.rc 리소스 파일을 추가하고 rc 파일 끝에 pipl 파일이 있습니다.

ps sdk는 공통 속성 정의를 포함한 공통 r 파일인 PIGeneral.r 파일을 제공했습니다.

(a) 다음으로 프로젝트에 r 파일을 추가하고 리소스 관리자에서 "Resource Files" 폴더를 마우스 오른쪽 버튼으로 클릭한 다음 클릭하여 새 파일을 추가하고 "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:CodesAdobe Photoshop CS2 SDKsamplecodecommonresourcesWinDialogUtils.r"
#endif

리소스 
'PiPL' ( 16000"FillRed", 삭제 가능 )
{
    {
        종류 { 필터 },
        이름 { plugInName },
        카테고리 { 
"데모 작성자:hoodlum1980" },
        버전 { (최신필터버전 
<< 16| latestFilterSubVersion },
        #ifdef __PIWin__
           CodeWin32X86 { 
"PluginMain" },
        
#else
            CodeMachOPowerPC { 
00"PluginMain" },
        
#endif

        지원되는 모드
        {
            noBitmap, doesSupportGrayScale,
            noIndexedColor, doesSupportRGBColor,
           doesSupportCMYKColor, doesSupportHSLColor,
            doesSupportHSBColor, doesSupportMultichannel,
            doesSupport Duotone, doesSupportLABColor
        },
           
        EnableInfo
        {
           
"에서 (PSHOP_ImageMode, GrayScaleMode, RGBMode,"
           
"CMYKMode, HSLMode, HSBMode , MultichannelMode,"
            
"DuotoneMode, LabMode,"
          
"Gray16Mode, RGB48Mode, CMYK64Mode, Lab48Mode)"
        },

        PlugInMaxSize { 
20000002000000 },

        FilterCaseInfo {
            {    
/ * 배열: 7개 요소 */                inStraightData,
               outStraightData,
              doNotWriteOutsideSelection,          > /* 선택 항목이 있는 평면 데이터 */
               inStraightData,
               outStraightData,
                doNotWriteOutsideSelection,
               doesNotFilterLayerMasks,
               doesNotWorkWithBlankData ,
               copySourceToDestination,
               
/* 플로팅 선택 */
                inStraightData,
                outStraightData,
               doNotWriteOutsideSelection,
               doesNotFilterLayerMasks,
               doesNotWorkWithBlankData,
               copySourceToDest ination,
               
/* 수정 가능 투명성, 선택 없음 */
               inStraightData,
               outStraightData,
               doNotWriteOutsideSelection,
                do esNotFilterLayerMasks,
               doesNotWorkWithBlankData,
                copySourceToDestination,
                
/* 선택 가능 투명성 */
               inStraightData,
               outStraightData,
                doNotWriteOutsideSelection,
> 🎜>/*

 투명성 유지, 선택 없음 
*/<                doesNotWorkWithBlankData,               copySourceToDestination,               /*

 보존된 투명성 선택 

*/


               inStraightData,
               outStraightData,               doNotWriteOutsideSelection > >        }    }};




 

                 FillRed.r文件中我们可以看到我们后右键点击该文件, 到后右键点击该文件, 然后右键点击该文件, 然后右键点击该文件, 该文件该文件, 所令镜分组name称 (카테고리)义生成规则的命令行中,点击编辑,输入以下内容:

                  

                '命令行'에서 一栏点击编辑按钮, 弹出的窗口中输入以下两行:

cl /I E:CodesAdobe ~1samplecodeCommon은 /IE:CodesAdobe~1PhotoshopAPIPhotoshop /IE:CodesAdobe~1PhotoshopAPIPICA_SP /IE:CodesAdobe~1samplecodeCommonResources /EP /DWIN32=1 /Tc"$(InputPath)" >를 포함합니다. "$(ProjectDir)$(InputName).rr"

Cnvtpipl.exe "$(ProjectDir)$(InputName).rr" "$(ProjectDir)$(InputName).pipl"

> 🎜>

第二行表示使用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\增效工具\滤镜”

                  포토샵 필터 작성 방법 (1)

 

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

                  포토샵 필터 작성 방법 (1)

Photoshop 도움말 메뉴의 하위 메뉴인 플러그인 정보에서 우리가 작성한 "FillRed Filter..." 항목을 볼 수 있습니다. 이 항목을 클릭하면 PS가 관련 호출을 시작하고 팝업이 표시됩니다. - 메시지박스.

                                                                                    ~       . 예를 들어 Photoshop SDK의 디렉터리는 특정 환경에 따라 조정되어야 합니다. 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 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

인기 기사

R.E.P.O. 에너지 결정과 그들이하는 일 (노란색 크리스탈)
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 최고의 그래픽 설정
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 아무도들을 수없는 경우 오디오를 수정하는 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. 채팅 명령 및 사용 방법
4 몇 주 전 By 尊渡假赌尊渡假赌尊渡假赌

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

소셜 미디어 그래픽을 만들기 위해 Photoshop을 어떻게 사용합니까? 소셜 미디어 그래픽을 만들기 위해 Photoshop을 어떻게 사용합니까? Mar 18, 2025 pm 01:41 PM

이 기사는 소셜 미디어 그래픽을위한 Photoshop, 설정, 설계 도구 및 최적화 기술을 사용하는 세부 사항에 대해 자세히 설명합니다. 그래픽 생성의 효율성과 품질을 강조합니다.

PS가 계속 로딩을 보여주는 이유는 무엇입니까? PS가 계속 로딩을 보여주는 이유는 무엇입니까? Apr 06, 2025 pm 06:39 PM

PS "로드"문제는 자원 액세스 또는 처리 문제로 인한 것입니다. 하드 디스크 판독 속도는 느리거나 나쁘다 : CrystalDiskinfo를 사용하여 하드 디스크 건강을 확인하고 문제가있는 하드 디스크를 교체하십시오. 불충분 한 메모리 : 고해상도 이미지 및 복잡한 레이어 처리에 대한 PS의 요구를 충족시키기 위해 메모리 업그레이드 메모리. 그래픽 카드 드라이버는 구식 또는 손상됩니다. 운전자를 업데이트하여 PS와 그래픽 카드 간의 통신을 최적화하십시오. 파일 경로는 너무 길거나 파일 이름에는 특수 문자가 있습니다. 짧은 경로를 사용하고 특수 문자를 피하십시오. PS 자체 문제 : PS 설치 프로그램을 다시 설치하거나 수리하십시오.

Photoshop (파일 크기, 해상도 최적화)을 사용하여 웹에 대한 이미지를 어떻게 준비합니까? Photoshop (파일 크기, 해상도 최적화)을 사용하여 웹에 대한 이미지를 어떻게 준비합니까? Mar 18, 2025 pm 01:35 PM

기사는 파일 크기 및 해상도에 중점을 둔 Photoshop을 사용하여 웹의 이미지 최적화에 대해 설명합니다. 주요 문제는 품질과로드 시간의 균형입니다.

Photoshop (해상도, 색상 프로파일)을 사용하여 인쇄 이미지를 준비하려면 어떻게해야합니까? Photoshop (해상도, 색상 프로파일)을 사용하여 인쇄 이미지를 준비하려면 어떻게해야합니까? Mar 18, 2025 pm 01:36 PM

이 기사는 Photoshop에서 인쇄 이미지를 준비하고 해상도, 색상 프로파일 및 선명도에 중점을 둡니다. 300 PPI 및 CMYK 프로파일은 품질 인쇄에 필수적이라고 주장합니다.

PS에서 PDF를 내보내는 것에 대한 일반적인 질문은 무엇입니까? PS에서 PDF를 내보내는 것에 대한 일반적인 질문은 무엇입니까? Apr 06, 2025 pm 04:51 PM

PDF로 PS를 내보낼 때 자주 묻는 질문 및 솔루션 : 글꼴 임베딩 문제 : "글꼴"옵션을 확인하고 "포함"을 선택하거나 글꼴을 곡선 (경로)으로 변환하십시오. 색상 편차 문제 : 파일을 CMYK 모드로 변환하고 색상을 조정하십시오. RGB로 직접 내보내려면 미리보기 및 색상 편차를위한 심리적 준비가 필요합니다. 해상도 및 파일 크기 문제 : 실제 조건에 따라 해상도를 선택하거나 압축 옵션을 사용하여 파일 크기를 최적화하십시오. 특수 효과 문제 : 내보내기 전에 층을 병합 (평평한).

Photoshop에서 애니메이션 GIF를 어떻게 만들려면? Photoshop에서 애니메이션 GIF를 어떻게 만들려면? Mar 18, 2025 pm 01:38 PM

기사는 기존 GIF에 프레임을 추가하는 것을 포함하여 Photoshop에서 애니메이션 GIF를 만들고 최적화하는 것을 논의합니다. 주요 초점은 품질 균형과 파일 크기에 있습니다.

Photoshop의 비디오 편집 기능을 어떻게 사용합니까? Photoshop의 비디오 편집 기능을 어떻게 사용합니까? Mar 18, 2025 pm 01:37 PM

이 기사는 비디오 편집에 Photoshop을 사용하고 비디오 가져 오기, 편집 및 내보내기위한 세부 사항 및 타임 라인 패널, 비디오 레이어 및 효과와 같은 주요 기능을 강조하는 방법을 설명합니다.

PS의 로딩 속도 속도를 높이는 방법? PS의 로딩 속도 속도를 높이는 방법? Apr 06, 2025 pm 06:27 PM

느린 Photoshop 스타트 업 문제를 해결하려면 다음을 포함한 다중 프론트 접근 방식이 필요합니다. 하드웨어 업그레이드 (메모리, 솔리드 스테이트 드라이브, CPU); 구식 또는 양립 할 수없는 플러그인 제거; 정기적으로 시스템 쓰레기 및 과도한 배경 프로그램 청소; 주의를 기울여 관련없는 프로그램 폐쇄; 시작하는 동안 많은 파일을 열지 않도록합니다.

See all articles