开发你的第一个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_ABOUTPF_Cmd_PARAMS_SETUPPF_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)
参数作用
cmdAE使用这个命令选择器来告知此插件主程序将要做什么,便于插件在内部针对相应的主程序事件进行响应,类似于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):适合自动化、批处理和快速开发的需求,开发难度较低。

根据具体需求选择合适的扩展方式,脚本可以满足述求的,用脚本的形式开发更简单些~

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值