You need to enable JavaScript to run this app.
导航
C接口快速接入指南
最近更新时间:2025.03.11 18:06:11首次发布时间:2022.02.25 17:16:51
我的收藏
有用
有用
无用
无用
iOS 项目中加入 SDK
  1. 项目中已使用 cocoapods,下一步参考 3,否则参考 2
  2. 在项目根目录,执行 pod init && pod install,可得到 Podfile 文件
  3. 打开 iossample 文件夹,拷贝 BytedEffectSDK.podspec、libeffect-SDK.a、include 到自己项目根目录
  4. 打开 Podfile 文件,增加一行 pod 'BytedEffectSDK', :path => './'
  5. 执行 pod install,并打开 项目名.xcworkspace,可以看到在 Pods/Development Pods 目录下已有 BytedEffectSDK
  6. 添加素材,将提供的素材包(一般是 resource 文件夹)添加到工程中
Android 项目中加入 SDK(以 C 接口方式)

通用做法

  1. 打开压缩包 byted_effect_andr.zip,再解压 android_c_sdk.zip

  2. 从aar文件里解压出来class.jar,拷贝jar包到项目主模块 libs 下,并确保主模块 build.gradle 的 dependencies 中有 api fileTree(include: ['*.jar'], dir: 'libs')

  3. 将 arm64-v8a 和 armeabi-v7a 下的 libeffect.so 添加到项目中

  4. 将 include 下的 SDK 头文件添加到项目中

  5. 添加素材,将提供的素材包(一般是 resource 文件夹)添加到工程中

注意事项:
Android端用C接口native接入的话(非hal的版本),还需要添加BEF_EFFECT_ANDROID_WITH_JNI预定义宏,指定要调用带jni环境的api,如下

cmake构建的话,通过以下方式添加

add_definitions(-DBEF_EFFECT_ANDROID_WITH_JNI=1)

Android.mk构建的话,通过以下方式添加

LOCAL_CFLAGS  += -DBEF_EFFECT_ANDROID_WITH_JNI=1

特殊情况下加入SDK(以C接口方式)

针对以下特殊情况,在加入sdk时有额外操作。

接入方有自己的lib库,并在lib中依赖sdk的libeffect.so, 或者使用dlopen的方式加载libeffect.so

这种情况下,android加载so时,调用不到sdk里面的JNI_OnLoad接口,导致sdk里一些方法没办法使用,最终引起执行出错。
针对这种情况,我们增加了以下两个接口,用来处理这个问题:

/**
 * @brief 主动调用effect_sdk的JNI_OnLoad
 * @param vm            表示 Java 虚拟机 的对象地址
 * @param reserved      传NULL即可
 * @return              返回当前 NDK 使用的 JNI 版本
*/
JNIEXPORT jint BEF_EFFECT_JNI_OnLoad(JavaVM* vm, void* reserved);
/**
 * @brief 主动调用effect_sdk的JNI_OnUnload
 * @param vm            表示 Java 虚拟机 的对象地址
 * @param reserved      传NULL即可
*/
JNIEXPORT void BEF_EFFECT_JNI_OnUnload(JavaVM *vm, void *reserved);

接入方在自己的lib中使用dlopen加载libeffect.so的方式时,可以参考如下方法和示例代码:

  1. 使用动态加载的方式获取到BEF_EFFECT_JNI_OnLoad以及BEF_EFFECT_JNI_OnUnload函数的函数地址,参考如下:
typedef void (*JNI_OnLoad_Def)(JavaVM *, void *);
typedef void (*JNI_OnUnload_Def)(JavaVM *, void *); 
// 1.加载libeffect.so 
void * handle = dlopen( libeffect.so ,RTLD_NOW | RTLD_LOCAL) 
if (handle) 
{ 
// 2.获取libeffect.so中 JNI_OnLoad和JNI_OnUnload的函数地址 
JNI_OnLoad_Def BEF_EFFECT_JNI_OnLoad_ptr = (JNI_OnLoad_Def)dlsym(handle, "BEF_EFFECT_JNI_OnLoad" ); 
JNI_OnUnload_Def BEF_EFFECT_JNI_OnUnload_ptr = (JNI_OnUnload_Def)dlsym(handle, "BEF_EFFECT_JNI_OnUnload" ); 
}
  1. JNI_Onload中调用BEF_EFFECT_JNI_OnLoad_ptrJNI_OnUnload中调用BEF_EFFECT_JNI_OnUnload_ptr
    注意
    BEF_EFFECT_JNI_OnLoad_ptr需要在java调用下来的native接口中调用才能生效(如JNI_OnLoad接口,或自定义的jni接口),不能直接在native层起的线程里去调用,否则会造成findclass失败。
  1. 包含以下的头文件到工程中,头文件命名为:bef_effect_jni_manager.h
#ifndef bef_effect_jni_manager_h
#define bef_effect_jni_manager_h
#include <jni.h>
#include "bef_effect_ai_public_define.h"

/**
 * @brief Actively call the JNI_OnLoad interface of effect_sdk.
 * @param vm          Object address representing the Java virtual machine.
 * @param reserved    just pass NULL.
 * @return            Returns the JNI version used by the current NDK.
 */
BEF_SDK_API jint BEF_EFFECT_JNI_OnLoad(JavaVM* vm, void* reserved);

/**
 * @brief Actively call the JNI_OnUnload interface of effect_sdk.
 * @param vm          Object address representing the Java virtual machine.
 * @param reserved    just pass NULL.
 */
BEF_SDK_API void BEF_EFFECT_JNI_OnUnload(JavaVM *vm, void *reserved);

#endif //bef_effect_jni_manager_h
  1. JNI_Onload中调用BEF_EFFECT_JNI_OnLoad接口,JNI_OnUnload中调用BEF_EFFECT_JNI_OnUnload接口
    注意
    BEF_EFFECT_JNI_OnLoad需要在java调用下来的native接口中调用才能生效(如JNI_OnLoad接口,或自定义的jni接口),不能直接在native层起的线程里去调用,否则会造成findclass失败。
Android 项目中加入 SDK(以 AAR 接口方式)
  1. 打开压缩包 byted_effect_andr.zip,找到 effect-SDKXXX.aar 文件
  2. 拷贝其到项目中的主模块(一般是 app)的 libs 目录下,如拷贝到 app/libs/ 目录(没有 libs 文件夹,可手动创建)
  3. 打开主模块(一般是 app)下的 build.gradle,在 android 下加入 SDK 查询路径:
repositories {
        flatDir {
            dirs 'libs'
        }
}
  1. 然后在主模块的 build.gradle 中的 dependencies 下加入 SDK 引用,implementation(name: 'effect-sdkXXX', ext: 'aar')
dependencies {
		implementation(name: 'effect-sdkXXX', ext: 'aar')
}
  1. 添加素材,将提供的素材包(一般是 resource 文件夹)拷贝到项目的 assets 中
代码中集成 SDK

以下指南针对使用 SDK 提供的 C 接口(或者是 Android 提供的 aar 接口)进行集成,会列出正常执行必需的一些步骤。只会列出美颜相关的接入流程,算法接入及更多接口,参见 算法接口说明特效接口说明

由于 SDK 本身只有图像的处理功能,像什么 OpenGL 相关的处理、绘制都没有,所以如果没有必要,建议直接使用 sample 中的一些封装代码接入。

准备阶段

  1. 确保项目中已有视频采集、图像渲染相关的能力,CV SDK 只针对某一帧画面做渲染,输入输出都以纹理形式(有处理 buffer 的接口,但本质还是先转成纹理再处理)
  2. 确保项目中已有 openGL 相关环境,关于 SDK 的所有函数,都要在 OpenGL 线程中调用,如不清楚参见 OpenGL 环境说明
  3. 确保素材包已经加入工程,Android 参见 素材拷贝说明

使用阶段

CV SDK 中美颜功能的接入可以分为三个阶段:

  1. 初始化 SDK
  2. 使用 SDK 进行图像处理
  3. SDK 参数设置,如设置美颜、贴纸、滤镜等

初始化 SDK

SDK 初始化需要以下几个函数的调用:

bef_effect_handle_t _handle;
int ret = 0;
// 创建 SDK 实例
ret = bef_effect_ai_create(&_handle);
// 进行 SDK 授权验证,此步骤不调用 handle 无法使用
ret = bef_effect_ai_check_license(_handle, self.licensePath);
// 设置是否使用并行渲染,默认可设置为开启
ret = bef_effect_ai_use_pipeline_processor(_handle, usePipeline);
// 执行 SDK 初始化,除了第四个参数需要传模型路径,也就是素材包中的 ModelResource.bundle 路径,其他的可参照示例
ret = bef_effect_ai_init(_handle, 10, 10, [[self.provider modelDirPath] UTF8String], "");
// 设置 SDK 美颜模式,按照示例调用即可
ret = bef_effect_ai_composer_set_mode(_handle, 1, 0);

如使用 Android 提供的 aar,对应的 java 方法为

public int init(Context context, 
                String modelDir,
                String licensePath,
                boolean usePipeline)

参数描述:

  1. context Android 中的 context
  2. modelDir 对应 bef_effect_ai_init 阶段的模型文件路径
  3. licensePath 对应 bef_effect_ai_check_license 阶段授权文件路径
  4. usePipeline 对应 bef_effect_ai_use_pipeline_processor 是否开启并行渲染

使用 SDK 进行图像处理

支持输入的数据类型

支持的数据类型支持的数据格式
buffer(不推荐)RGBA、BGRA、YUV
texture2D

SDK 处理图像时有两类接口,可以分别处理 buffer 类型输入和纹理输入,注意,推荐使用纹理输入,如果目前项目中只能提供 buffer,建议先转成纹理再处理,外部可以做一些特殊优化,但如果直接给 SDK 输入 buffer,会很影响性能。

处理纹理输入

纹理输入需要调用的函数:

int ret;
// 设置图像宽高,注意,如果前后两帧处理的图像大小不一致,可能会导致效果异常
ret = bef_effect_ai_set_width_height(_handle, width, height);
// 设置图像旋转角度,一般直接取系统提供的手机旋转方向即可
ret = bef_effect_ai_set_orientation(_handle, orientation);
// 对图像做算法处理,调用此函数才会执行人脸检测
// 本函数中只有 texture 和 timeStamp 是必需的,比如可以直接调用 bef_effect_ai_algorithm_texture_with_buffer(_handle, texture, NULL, 0, 0, 0, 0, timeStamp);
// 另外几个参数为对 buffer 的描述,将 buffer 与 texture 一起使用在某些场景有加速效果,一般情况下只传 texture 即可 
ret = bef_effect_ai_algorithm_texture_with_buffer(_handle, texture, buffer, format, width, height, bytesPerRow, timeStamp);
// 对图像做特效处理,调用此函数才会增加美颜效果
// 注意,输入输出纹理需要保持宽高一致,且不要让二者共用同一纹理
ret = bef_effect_ai_process_texture(_handle, inputTexture, outputTexture, timeStamp);

如使用 Android 提供的 aar,对应的 java 方法为

// bef_effect_ai_set_width_height bef_effect_ai_set_orientation 已在内部调用,可不用关
// 对应 bef_effect_ai_algorithm_texture_with_buffer
public boolean algorithmTextureWithBuffer(int texture,
                                          ByteBuffer buffer, 
                                          BytedEffectConstants.Rotation orient, 
                                          int pixelFormat, 
                                          int width, 
                                          int height, 
                                          int stride, 
                                          long timeStamp)
// 对应 bef_effect_ai_process_texture
public boolean processTextureOnly(int srcTexture,
                                  int dstTexture,
                                  int width, 
                                  int height, 
                                  BytedEffectConstants.Rotation rotation,
                                  long timeStamp)

处理 buffer 输入

int ret;
// 设置图像宽高,注意,如果前后两帧处理的图像大小不一致,可能会导致效果异常
ret = bef_effect_ai_set_width_height(_handle, width, height);
// 设置图像旋转角度,一般直接取系统提供的手机旋转方向即可
ret = bef_effect_ai_set_orientation(_handle, orientation);
// 对图像做算法处理,调用此函数才会执行人脸检测
ret = bef_effect_ai_algorithm_buffer(_handle, buffer, format, width, height, bytesPerRow, timeStamp);
// 对图像做特效处理,调用此函数才会增加美颜效果
// 注意,outputBuffer 为处理结果保存的位置,一定要保证它的内存大小与给定的图像宽高和格式相符合
ret = bef_effect_ai_process_buffer(_handle, inputBuffer, inputFormat, width, height, bytesPerRow, outputBuffer, outputFormat, timeStamp);

如使用 Android 提供的 aar,对应的 java 方法为

public boolean processBuffer(ByteBuffer inputdata,
                             BytedEffectConstants.Rotation orient,
                             int in_pixformat,
                             int imagew, 
                             int imageh,
                             int imagestride,
                             byte[] outdata,
                             int out_pixformat)

SDK 参数设置,如设置美颜、贴纸、滤镜

注意,SDK 参数设置需要在初始化之后调用,请尽量与 SDK图像处理 处于同一线程使用,以避免可能出现的问题。

设置美颜、美型、美妆

美颜、美型、美妆的设置使用的是同一个接口,一般来说使一个美颜生效需要两步:

  1. 设置素材对应的路径
  2. 设置素材中,特效的强度(一般强度默认为 0,所以这一步不执行会没有效果)

设置素材路径接口

// 设置素材
bef_effect_result_t result = bef_effect_ai_composer_set_nodes(_handle, (const char **)nodesPath, count);

如使用 Android 提供的 aar,对应的 java 方法为

public int setComposerNodes(String[] composerNodes)

nodesPath 是字符串数组,每一行代表一个素材在设备中的绝对路径

注意,SDK 内部不会保存已设置的素材,所以此方法每次调用都需要将所有需要生效的素材路径加上。

设置素材中,特效强度接口

// 设置素材中某个特效的强度
bef_effect_result_t result = bef_effect_ai_composer_update_node(_handle, (const char *)node, (const char *)key, intensity);

如使用 Android 提供的 aar,对应的 java 方法为

public int updateComposerNodes(String path,
                               String key, 
                               float value)

node 为素材在设备中的绝对路径。

以美颜素材为例,需要通过 key 来控制我们要修改的是美白、磨皮还是锐化的强度,素材中 key 与功能的对应关系参见 素材 key 对应说明

设置贴纸

设置贴纸接口

// 设置贴纸
bef_effect_result_t result = bef_effect_ai_set_effect(_handle, (const char *)path);

如使用 Android 提供的 aar,对应的 java 方法为

public boolean setSticker(String resourcePath)

path 为贴纸在设备中的绝对路径。

设置滤镜

设置滤镜的接口

// 设置滤镜路径
bef_effect_result_t result = bef_effect_ai_set_color_filter_v2(_handle, path);

// 设置滤镜强度
result = bef_effect_ai_set_intensity(_handle, BEF_INTENSITY_TYPE_GLOBAL_FILTER_V2, intensity);

如使用 Android 提供的 aar,对应的 java 方法为

// 对应 bef_effect_ai_set_color_filter_v2
public boolean setFilter(String resourcePath);
// 对应 bef_effect_ai_set_intensity
public boolean updateIntensity(BytedEffectConstants.IntensityType.Filter.getId(), float intensity)

path 为滤镜在设备中的绝对路径。