You need to enable JavaScript to run this app.
导航

Android

最近更新时间2022.02.28 19:42:09

首次发布时间2022.02.25 17:16:51

项目中加入SDK
  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')
  2. 添加素材,将提供的素材包(一般是 resource 文件夹)拷贝到项目的 assets 中
代码中集成SDK

以下指南针对使用 sample 中封装的 Java 代码进行集成,如果直接在项目中使用 CV SDK 提供的 C 接口集成,参见 接口说明-特效接口说明-算法

准备阶段

  1. 拷贝 androidsample 项目中的 com.bytedance.labcv.demo.core.v4 包到自己的工程中,这部分是 SDK 的封装接口,主要操作的类为 EffectHelper
  2. 将素材拷贝代码 com.bytedance.labcv.demo.task.UnzipTask 及相关逻辑 com.bytedance.labcv.demo.presenter.WelcomePresenter 应用到自己项目中(没有此步骤,素材无法使用),更多内容参见 素材拷贝说明

以上为主要接口,以上代码可能会对 sample 中的其他代码有依赖,可将这些也拷贝到自己项目中。

使用阶段

SDK 的统一封装接口为 EffectHelper,SDK 的使用可以分为三个阶段:

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

**注意,SDK 的所有操作都应该在 openGL 线程中执行。**如果是在推流 SDK 中集成,一般直接在推流 SDK 提供的自定义美颜接口中进行即可,如果是本地环境,一般与 SurfaceView 一起使用,并在它提供的 openGL 环境中使用 CV SDK。

1.初始化 SDK

初始化的调用时机一般在 openGL 环境初始化完成后,如在 onSurfaceCreated 中(如使用推流 SDK,一般在推流 SDK 提供的初始化自定义美颜的接口)执行,需要调用的函数为:

mEffectHelper = new EffectHelper(mContext, EffectManager.EffectType.PREVIEW);
mEffectHelper.init();

其中 EffectManager.EffectType 参数一般可使用 PREVIEW。

2.使用 SDK 进行图像处理

支持的输入数据类型

支持的数据类型支持的数据格式
textureOES,2D

图像处理的调用,在 onDrawFrame 中执行(如果使用推流 SDK,可在推流 SDK 提供的接口中调用),对应的函数为:

mDstTexture = mEffectHelper.processTexture(mCameraProxy.getPreviewTexture(), BytedEffectConstants.TextureFormat.Texture_Oes, mCameraProxy.getPreviewWidth(), mCameraProxy.getPreviewHeight(), mCameraProxy.getOrientation(), mCameraProxy.isFrontCamera(), rotation, mCameraProxy.getTimeStamp());

参数说明:

参数名含义
srcTextureId待处理的输入纹理
srcTextureFormat输入纹理类型,有 OES 纹理(Android 中特有,一般 camera 直出的纹理就是这种)和 2D 纹理两种
srcTextureWidth输入纹理宽
srcTextureHeight输入纹理高
cameraRotation相机旋转角度,可选值为0/90/180/270,理解为,图像需要旋转这个角度,才能使人脸转正
frontCamera当前是否采用前置摄像头
sensorRotation手机角度,通过手机传感器取得
timeStamp当前时间,参见 timeStamp获取

处理结果:

process 方法的输出为渲染后的 2D 纹理。

注意,不推荐使用 SDK 直接处理 buffer,SDK 最终需要接收的是待处理纹理,如需要处理 buffer,建议先将 buffer 转成纹理使用,但这会造成耗时增加。

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

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

(1)设置美颜、美型、美妆

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

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

设置素材路径接口

/**
 * 设置特效组合,目前支持美颜、美形、美体、 美妆特效的任意叠加
 */
boolean setComposeNodes(String[] nodes);

// 示例
mEffectHelper.setComposeNodes(new String[]{"beauty_Android_live"});

此处的素材路径,是相对于 ComposeMakeup.bundle/ComposeMakeup 的路径,素材包结构参见 素材包结构说明

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

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

/**
 * 更新组合特效(美颜、美形、美体、 美妆)中某个节点的强度
 */
boolean updateComposeNode(ComposerNode node, boolean update);

// 示例
mEffectHelper.updateComposeNode(new ComposerNode(TYPE_BEAUTY_FACE, "beauty_Android_live", "whiten", 0.8f), true);

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

(2)设置贴纸

设置贴纸接口

/**
 * 开启或者关闭贴纸 如果path为空 关闭贴纸
 * @param path 贴纸素材的文件路径
 */
boolean setSticker(String path);

// 示例
mEffectHelper.setSticker("baibianfaxing");

此处的贴纸路径为素材包中 StickerResource.bundle/stickers 中的相对路径。

(3)设置滤镜

/**
 * 开启或者关闭滤镜 如果path为空 关闭滤镜
 *
 * @param path path of filter file 滤镜资源文件路径
 */
boolean setFilter(String path);

/**
 * 设置滤镜强度
 *
 * @param intensity intensity 参数值
 */
boolean updateFilterIntensity(float intensity);

// 示例
mEffectHelper.setFilter("Filter_01_38");
mEffectHelper.updateFilterIntensity(0.8f);

此处的滤镜路径为素材包中 FilterResource.bundle/Filter 中的相对路径。

4.SDK 算法功能使用

开启算法

对应接口:

/**
 * add an algorithm task with key
 * @param config key of task
 * @param flag open the algorithm if true, or close if false
 */
void addAlgorithmTask(TaskKey config, boolean flag);

// 示例,打开人脸 106 检测算法
mEffectHelper.addAlgorithmTask(FaceAlgorithmTask.FACE_106, true);

更多的算法 key 对应关系参见 算法 key 与返回结果类型一览

算法结果回调

添加/移除结果回调接口:

/**
 * add a callback of a result
 * @param callback callback
 * @param <T> type of result
 */
<T> void addResultCallback(ResultCallback<T> callback);

/**
 * remove a callback of a result
 * @param callback callback
 * @param <T> type of result
 */
<T> void removeResultCallback(ResultCallback<T> callback);

// 示例,添加人脸检测结果回调
mEffectHelper.addResultCallback(new AlgorithmInterface.ResultCallback<BefFaceInfo>() {
    @Override
    protected void doResult(BefFaceInfo befFaceInfo, int framecount) {
        // todo
    }
});

这里主要是通过类型 BefFaceInfo 来判断这是哪个算法结果的回调,更多的返回结果对应关系,参见 算法 key 与返回结果类型一览

附录:素材拷贝说明

android 中内置素材时是把素材放到 asset 中,这里面的文件内容无法通过路径获取,所以 sample 中的做法是在初次启动 app 时将其拷贝到应用私有目录中,通过 com.bytedance.labcv.demo.task.UnzipTask 完成,如果需要拷贝的素材过多,可能会导致启动时间太长,对此有以下参考方法:

  1. 只将一些很简单的素材,如美颜、美型等内置
  2. 贴纸这种比较大的,可以做成在线下发,在 app 需要用到的时候通过网络下载到本地,既可以降低包大小,也可以提升启动速度
附录:timeStamp 获取

如果是使用相机采集数据,并使用了 SurfaceTexture 作为输出数据容器,可以直接调用它的 getTimestamp 方法:

long timeStamp = surfaceTexture.getTimestamp();

否则使用系统方法:

long timeStamp System.currentTimeMillis();
附录:EffectHelper 类型

三种不同的类型主要在与对于输入纹理的处理和绘制上的区别,具体看下面。

类型process 函数区别输出纹理
PREVIEWprocessTexture会根据传进来的 srcTextureFormat、 cameraRotation 和 sensorRotation 对纹理做旋转,更容易保证效果正确,但由于需要两次旋转,性能较差输出纹理与输入纹理方向相同
VIDEOprocessVideoTexture会根据传进来的 srcTextureFormat 和 videoRotation 对纹理做旋转,需要做一次旋转输出纹理保持为正向,不一定与输入纹理同方向
IMAGEprocessImageTexture不对纹理做预处理,需要保证传进来的纹理是 2D 且人脸是正的方向,相对的性能也更好输入与输入同向,未做任何旋转
附录:算法 key 与返回结果类型一览
算法key返回结果
人脸检测FaceAlgorithmTask#FACE_106(106 点) FaceAlgorithmTask#FACE_280(280 点) FaceAlgorithmTask#FACE_ATTR(人脸属性) FaceAlgorithmTask#FACE_MASK(人脸 mask) FaceAlgorithmTask#MOUTH_MASK(嘴唇 mask) FaceAlgorithmTask#TEETH_MASK(牙齿 mask)com.bytedance.labcv.effectsdk.BefFaceInfo
AnimojiAnimojiAlgorithmTask#ANIMOJIcom.bytedance.labcv.effectsdk.BefAnimojiInfo
C1 场景分类C1AlgorithmTask.C1com.bytedance.labcv.effectsdk.BefC1Info
C2 场景分类C2AlgorithmTask.C2com.bytedance.labcv.effectsdk.BefC2Info
车辆检测CarDetectTask.CAR_DETECT CarDetectTask.CAR_RECOG(车辆检测) CarDetectTask.BRAND_RECOG(车牌检测)com.bytedance.labcv.effectsdk.BefCarDetectInfo
专注度检测ConcentrationTask.CONCENTRATIONcom.bytedance.labcv.demo.core.v4.algorithm.task.ConcentrationTask.BefConcentrationInfo
视线估计GazeEstimationTask.GAZE_ESTIMATIONcom.bytedance.labcv.effectsdk.BefGazeEstimationInfo
头发分割HairParserAlgorithmTask.HAIR_PARSERcom.bytedance.labcv.effectsdk.HairParser
手势检测HandAlgorithmTask.HANDcom.bytedance.labcv.effectsdk.BefHandInfo
人头分割HeadSegmentAlgorithmTask.HEAD_SEGMENTcom.bytedance.labcv.effectsdk.BefHeadSegInfo
距离估计HumanDistanceAlgorithmTask.HUMAN_DISTANCEcom.bytedance.labcv.effectsdk.BefDistanceInfo
光线分类LightClsAlgorithmTask.LIGHT_CLScom.bytedance.labcv.effectsdk.BefLightclsInfo
宠物脸检测PetFaceAlgorithmTask.PET_FACEcom.bytedance.labcv.effectsdk.BefPetFaceInfo
人体分割PortraitMattingAlgorithmTask.PORTRAIT_MATTINGcom.bytedance.labcv.effectsdk.PortraitMatting.MattingMask
骨骼检测SkeletonAlgorithmTask.SKELETONcom.bytedance.labcv.effectsdk.BefSkeletonInfo
天空分割SkySegmentAlgorithmTask.SKY_SEGMENTcom.bytedance.labcv.effectsdk.BefSkyInfo
视频分类VideoClsAlgorithmTask.VIDEO_CLScom.bytedance.labcv.effectsdk.BefVideoClsInfo