一、环境准备
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):适合自动化、批处理和快速开发的需求,开发难度较低。
根据具体需求选择合适的扩展方式,脚本可以满足述求的,用脚本的形式开发更简单些~
1521

被折叠的 条评论
为什么被折叠?



