问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

开发你的第一个AE插件

创作时间:
作者:
@小白创作中心

开发你的第一个AE插件

引用
CSDN
1.
https://m.blog.csdn.net/vicki2017/article/details/142653085

Adobe After Effects(AE)插件开发是一个相对小众但专业性很强的领域。本文将从环境准备、AE模板工程入口文件分析、开始开发、调试、插件安装使用,以及AE插件与脚本的对比等多个方面详细介绍了AE插件的开发流程。

一、环境准备

  1. Adobe After Effects 2024
    1.1 下载地址:Adobe官网
    1.2 模板工程下载:https://developer.adobe.com/console/1367532/user/servicesandapis
    若无权限, 可访问github获取

  2. Microsoft Visual Studio
    下载地址:https://visualstudio.microsoft.com/zh-hans/downloads/
    配置好c++开发环境后,打开AE模板工程,右键 > 属性

2.1 设置插件输出目录到环境变量

2.2 设置window调试器目录到环境变量
这是方便所有项目统一配置,另外再设置一下

二、AE模板工程入口文件分析

函数 作用
About 插件的关于信息, 用于显示描述插件的对话框
GlobalSetup 插件的全局状态和资源初始化,在插件加载时被调用一次,因此可以在这里执行一些一次性的初始化操作,比如分配内存、加载资源、设置全局变量等
ParamsSetup 插件UI初始化, 是设置 UI、描述参数和注册它们的函数
Render 渲染,在首次应用插件,以及更改插件参数值时执行, 是根据输入和参数将效果渲染到输出的函数
EffectMain 根据用户操作,进入不同处理函数。EffectMain 是接受PF_Cmd cmd作为一个参数的函数,并使用(如PF_Cmd_ABOUT,PF_Cmd_PARAMS_SETUP和PF_Cmd_RENDER的) cmd 作为一个选择器来调用该函数。参考AE 插件 SDK 指南命令选择器

入口函数EffectMain参数说明

EffectMain(  
    PF_Cmd			cmd,  
    PF_InData		*in_data,  
    PF_OutData		*out_data,  
    PF_ParamDef		*params[],  
    PF_LayerDef		*output,  
    void			*extra)  

参数 作用
cmd AE使用这个命令选择器来告知此插件主程序将要做什么,便于插件在内部针对相应的主程序事件进行响应,类似于Win32中的消息队列的作用
in_data 此参数包含了主程序的状态和那些可以被本插件操作的数据。此指针还提供了大量与界面和图像处理相关的作用
out_data 此参数的作用是把经过插件处理后的数据,通过out_data参数传回给AE
params 插件参数数组
output 此参数包含了被此特效插件渲染后输出的图像信息,最终会被传回到AE中。只有在某些特定的选择器中此参数才有效
extra 额外参数会根据发送的命令或(在 PF_Cmd_EVENT 的情况下)事件类型而变化。主要用于事件管理和参数监督

三、开始开发啦

功能: 在插件的用户界面中添加按钮,点击触发提示用户按钮点击次数

代码实现:

Template/Skeleton/Skeleton.h

...  
#define PLUGIN_NAME "Demo"  
#define BUTTON_PARAM_ID 1  
#define NUM_PARAMS 2 // 包括一个按钮参数和一个结束标记参数  
...  
typedef struct {  
    AEGP_PluginID my_id;  
    int click_count; // 记录按钮点击次数  
} MyGlobalData;  
static MyGlobalData g_my_global_data;  
extern "C" {  
    DllExport  
    PF_Err  
    EffectMain(  
        PF_Cmd			cmd,  
        PF_InData		*in_data,  
        PF_OutData		*out_data,  
        PF_ParamDef		*params[],  
        PF_LayerDef		*output,  
        void			*extra);  
}  
...  

Template/Skeleton/Skeleton.cpp

...  
static PF_Err  
GlobalSetup (  
    PF_InData		*in_data,  
    PF_OutData		*out_data,  
    PF_ParamDef		*params[],  
    PF_LayerDef		*output )  
{  
    out_data->my_version = PF_VERSION(	MAJOR_VERSION,  
                                        MINOR_VERSION,  
                                        BUG_VERSION,  
                                        STAGE_VERSION,  
                                        BUILD_VERSION);  
    out_data->out_flags =  PF_OutFlag_DEEP_COLOR_AWARE;	// just 16bpc, not 32bpc  
    // 获取插件的 AEGP_PluginID  
    AEGP_SuiteHandler suites(in_data->pica_basicP);  
    suites.UtilitySuite3()->AEGP_RegisterWithAEGP(NULL, PLUGIN_NAME, &g_my_global_data.my_id);  
    g_my_global_data.click_count = 0; // 初始化点击次数  
    return PF_Err_NONE;  
}  
static PF_Err  
ParamsSetup (  
    PF_InData		*in_data,  
    PF_OutData		*out_data,  
    PF_ParamDef		*params[],  
    PF_LayerDef		*output )  
{  
    PF_Err		err		= PF_Err_NONE;  
    PF_ParamDef	def;  
     // 清除结构体  
    AEFX_CLR_STRUCT(def);  
    // 定义按钮  
    PF_ADD_BUTTON(  
        "Click Me",        // PARAM_NAME  
        "Click",           // BUTTON_NAME  
        0,                 // PUI_FLAGS  
        PF_ParamFlag_SUPERVISE, // PARAM_FLAGS  
        BUTTON_PARAM_ID    // ID  
    );  
    // 设置参数数量  
    out_data->num_params = NUM_PARAMS;  
    return err;  
}  
// 处理按钮点击事件  
static PF_Err HandleButtonClick(PF_InData* in_data, PF_OutData* out_data, PF_ParamDef* params[], PF_LayerDef* output) {  
    PF_Err err = PF_Err_NONE;  
    g_my_global_data.click_count++; // 增加点击次数  
    AEGP_SuiteHandler suites(in_data->pica_basicP);  
    suites.ANSICallbacksSuite1()->sprintf(out_data->return_msg, "Button clicked %d times!", g_my_global_data.click_count);  
    return err;  
}  
// 插件入口函数  
PF_Err  
EffectMain(  
    PF_Cmd			cmd,  
    PF_InData		*in_data,  
    PF_OutData		*out_data,  
    PF_ParamDef		*params[],  
    PF_LayerDef		*output,  
    void			*extra)  
{  
    PF_Err		err = PF_Err_NONE;  
    try {  
        switch (cmd) {  
            case PF_Cmd_ABOUT:  
                err = About(in_data,  
                            out_data,  
                            params,  
                            output);  
                break;  
            case PF_Cmd_GLOBAL_SETUP:  
                err = GlobalSetup(	in_data,  
                                    out_data,  
                                    params,  
                                    output);  
                break;  
            case PF_Cmd_PARAMS_SETUP:  
                err = ParamsSetup(	in_data,  
                                    out_data,  
                                    params,  
                                    output);  
                break;  
            case PF_Cmd_USER_CHANGED_PARAM:  
                {  
                    // 在新的作用域中声明和初始化 extraP  
                    PF_UserChangedParamExtra* extraP = reinterpret_cast<PF_UserChangedParamExtra*>(extra);  
                    if (extraP->param_index == BUTTON_PARAM_ID) {  
                        err = HandleButtonClick(in_data, out_data, params, output);  
                    }  
                }  
                break;  
            case PF_Cmd_RENDER:  
                err = Render(	in_data,  
                                out_data,  
                                params,  
                                output);  
                break;  
            default:            
                break;  
        }  
    }  
    catch(PF_Err &thrown_err){  
        err = thrown_err;  
    }  
    return err;  
}  
...  

四、调试

4.1 点击解决方案 → 生成/重新生成

4.2 点击
本地Window调试器
,即可启动AE验证调试插件效果

代码错误弹窗提示:
在AE中执行,
编辑>清理>所有[Edit > Purge > All]
命令,它将会清理所有相同特效插件占用的内存,就不用每次都重新启动
这样我们可以成功运行和调试插件,剩下的就是啃API文档~

五、插件安装&使用

将生成的插件文件 .aex 文件复制到 After Effects 插件目录中。默认情况下,插件目录路径如下:

Windows:
C:\Program Files\Adobe\Adobe After Effects <版本号>\Support Files\Plug-ins\

如果 After Effects 已经在运行,请关闭并重新启动软件,以便新安装的插件生效

六、AE插件 VS 脚本

对比项 插件(Plug-ins) 脚本(Scripts)
性能 高性能,适合处理复杂的图像处理任务和实时效果。 性能较低,适合自动化任务和批处理操作。
功能 可以直接操作图像数据,创建复杂的视觉效果,如粒子系统、3D 渲染等。 可以控制 After Effects 的大部分功能,如创建和修改图层、关键帧、合成等,但不能直接操作图像数据。
用户界面 可以创建自定义的用户界面,提供丰富的交互功能。 可以创建简单的用户界面(如对话框、面板),但交互性和复杂度不如插件。
集成度 深度集成到 After Effects 中,作为效果(Effect)或生成器(Generator)使用。 通过 ExtendScript 控制 After Effects 的功能,适合自动化和批处理任务。
API 使用 Adobe 提供的 After Effects SDK,主要用 C++ 编写。 使用 ExtendScript(Adobe 的 JavaScript 变体),适合有 JavaScript 基础的开发者。
开发难度 较高,需要熟悉 C++ 和图像处理技术。 较低,适合快速开发和调试。
网络功能 可以使用标准的 C++ 网络库(如 libcurl)进行 HTTP 请求,但需要自行处理网络通信和数据解析。 ExtendScript 本身不支持直接进行 HTTP 请求,但可以通过调用外部工具(如 curl)或使用 Adobe CEP 进行网络通信。
应用场景 复杂效果、高性能需求、深度集成。 自动化任务、批处理、快速开发、简单交互。
常见用途 粒子系统、3D 渲染、图像滤镜、实时数据获取。 项目管理、图层操作、关键帧设置、渲染队列管理、参数获取。

小结

  • 插件(Plug-ins):适合高性能、复杂效果和深度集成的需求,但开发难度较高。
  • 脚本(Scripts):适合自动化、批处理和快速开发的需求,开发难度较低。
    根据具体需求选择合适的扩展方式,脚本可以满足述求的,用脚本的形式开发更简单些~
© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号