接口文档

Beauty AR SDK 核心接口类 XmagicApi.java,用于初始化 SDK、更新美颜数值、调用动效等功能。
各 API 整体调用流程如下:




XmagicApi 的静态属性和方法列表

API
描述
VERSION
通过 XmagicApi.VERSION 可获取 SDK 的版本号(V3.5.0新增)。
设置 so 库的路径,如果 so 库是内置在 apk 包里的,则无需使用该接口。
将应用程序 assets 下 Light3DPlugin、LightCore、LightHandPlugin、LightBodyPlugin、LightSegmentPlugin 文件夹中的内容复制到指定目录中。
将客户下载好的 AI 模型文件复制到对应的文件夹下。
获取设备等级。

XmagicApi 的 Public 方法列表

API
描述
XmagicApi
构造函数。
process
SDK 渲染数据的方法,用于处理图片或视频流。
setEffect
设置美颜、美型、滤镜、美妆、贴纸、分割等效果,可在任意线程调用。
设置 SDK 的 log 等级,默认为Log.WARN。开发调试阶段如有需要,可以将其设为Log.DEBUG。正式发布时务必设置为Log.WARNLog.ERROR,否则大量的日志会影响性能。
在 new XmagicApi() 之后调用。
调用此方法开启高性能模式。高性能模式开启后,美颜占用的系统 CPU/GPU 资源更少,可减少手机的发热和卡顿现象,更适合低端机长时间使用。
在 new XmagicApi() 之后调用。
开启或关闭某个能力。
设置输入数据类型,有相机数据和图片数据两类,默认是相机数据流。
设置人脸、手势、身体检测状态回调。
动效素材使用时是否开启静音。参数:true 表示静音,false 表示非静音。
onPause
暂停特效里的声音播放,可与 Activity onPause 生命周期绑定。
onResume
恢复特效里的声音播放,可与 Activity onResume 生命周期绑定。
onDestroy
销毁 xmagic,需要在 GL 线程中调用。
设置图像方向,使 AI 对不同朝向的人脸都能识别到,如果设置,则忽略 sensorChanged 传入的方向。
利用系统传感器判断当前手机旋转的角度,使 AI 对不同朝向的人脸都能识别到。
将一个动效素材的路径传给SDK,检测当前设备是否完全支持这个动效。
判断当前机型是否支持美颜(OpenGL3.0)。
获取当前纹理上的画面
设置动效提示语回调函数,用于将提示语展示到前端页面上。
设置同步处理视频帧。

静态方法 setLibPathAndLoad

设置 so 库的路径,并触发加载。
如果 so 库是内置在 apk 包里的,则无需使用该接口。如果 so 是动态下载的,则需要在鉴权和 new XmagicApi() 之前调用。
传入 null :表示从默认路径加载 so,请确保 so 是内置在 APK 包里的。
传入非 null:如 data/data/包名/files/xmagic_libs,将从这个目录去加载 so。
static boolean setLibPathAndLoad(String path)

静态方法 addAiModeFilesFromAssets

SDK 的模型资源文件,可以内置在 apk 包的 assets 目录,也可以动态下载。如果是内置在 assets 里的,那么首次使用 SDK 之前,需要将 assets 下的模型资源文件复制到指定目录中。这个操作只需要做一次。在您升级 SDK 版本之后,才需要再执行一次。
context 应用上下文。
resDir 用于存放 SDK 模型资源的根目录,此目录和创建 new XmagicApi() 对象时传入的路径参数一致。
返回值:
0:复制成功
-1:表示 context 为 null
-2:表示 IO 错误
static int addAiModeFilesFromAssets(Context context, String resDir)

静态方法 addAiModeFiles

如果您未将 SDK 的模型资源文件内置在 APK 包里,而是动态下载,那么下载成功并解压后,可以调用此方法将下载好的 SDK 模型资源文件复制到对应的文件夹下。
inputResDir 下载成功的模型文件的文件夹。
resDir 用于存放 SDK 模型资源的根目录,此目录和创建 new XmagicApi() 对象时传入的路径参数一致。
返回值:
0:表示成功
-1:inputResDir is not exists
-2:表示 IO 错误
static int addAiModeFiles(String inputResDir, String resDir)

静态方法 getDeviceLevel

获取设备等级,V3.7.0新增。您可以根据设备等级 开启或关闭 SDK 的相关功能,或在低等级手机上设置 高性能模式
注意:
V3.7.0 - V3.9.0期间,如果您需要在new XmagicApi之前就调用 getDeviceLevel 方法,则需要将 SDK 的 assets 目录下的 benchmark 文件夹内置在您的 APK 的 assets 里。如果在 new XmagicApi之后才调用 getDeviceLevel,则无需内置。
我们将在V3.9.1版本优化此问题。
static DeviceLevel getDevicLevel(Context context)

public enum DeviceLevel {
DEVICE_LEVEL_VERY_LOW(1),
DEVICE_LEVEL_LOW(2),
DEVICE_LEVEL_MIDDLE(3),
DEVICE_LEVEL_MIDDLE_HIGH(4),
DEVICE_LEVEL_HIGH(5);

private final int value;

DeviceLevel(int value) {
this.value = value;
}

public int getValue() {
return value;
}
}

XmagicApi 构造方法

public XmagicApi(Context context, EffectMode effectMode, String resDir)

public XmagicApi(Context context, EffectMode effectMode, String resDir,OnXmagicPropertyErrorListener xmagicPropertyErrorListener)

@Deprecated
public XmagicApi(Context context, String resDir)
@Deprecated
public XmagicApi(Context context, String resDir,OnXmagicPropertyErrorListener xmagicPropertyErrorListener)

public interface OnXmagicPropertyErrorListener {
void onXmagicPropertyError(String errorMsg, int code);
}

public enum EffectMode{
NORMAL(0),
PRO(1);

private final int value;

EffectMode(int value) {
this.value = value;
}

public int getValue() {
return value;
}
}
参数
类型
含义
context
Context
上下文。
effectMode
EffectMode
V3.9.0新增此参数。
用于指定性能和效果模式,可取值 NORMAL 和 PRO。NORMAL 能满足大部分场景,性能更好,但功能会少一些,请按需选用。
resDir
String
SDK 模型资源文件目录。
在使用 SDK 之前,需要先确定一个目录用于存放 SDK 的模型资源文件,建议使用 app 私有目录:
resDir = context.getFilesDir().getAbsolutePath() + "/xmagic"
并且在 new XmagicApi 之前,请先调用 XmagicApi 的静态方法 addAiModeFilesFromAssetsaddAiModeFiles 将模型资源文件 copy 到 resDir。
xmagicPropertyErrorListener
OnXmagicPropertyErrorListener
错误回调接口。在使用 SDK 过程中,此接口会回调内部的一些错误信息。一般在开发调试时使用。
OnXmagicPropertyErrorListener 返回错误码含义对照表:
错误码
含义
-1
未知错误。
-100
3D 引擎资源初始化失败。
-200
不支持 GAN 素材。
-300
设备不支持此素材组件。
-400
模板 JSON 内容为空。
-500
SDK 版本过低。
-600
不支持分割。
-700
不支持 OpenGL。
-800
不支持脚本。
5000
分割背景图片分辨率超过 2160×3840。
5001
分割背景图片所需内存不足。
5002
分割背景视频解析失败。
5003
分割背景视频超过200秒。
5004
分割背景视频格式不支持。
5005
分割背景图片存在旋转角度

process

SDK 渲染数据的方法,用于处理图片或视频流。处理视频流时,可在相机数据回调函数内使用。
//渲染纹理
int process(int srcTextureId, int srcTextureWidth, int srcTextureHeight)
//渲染bitmap
Bitmap process(Bitmap bitmap, boolean needReset)
参数
含义
int srcTextureId
需要被渲染的纹理。类型为:OpenGL 2D 纹理格式,像素格式为 RGBA。
int srcTextureWidth
需要被渲染的纹理宽。
int srcTextureHeight
需要被渲染的纹理高。
Bitmap bitmap
建议最大尺寸 2160×4096。超过这个尺寸的图片人脸识别效果不佳或无法识别到人脸,同时容易引起 OOM 问题,建议把大图缩小后再传入。
boolean needReset
以下几种场景请将 needReset 设置为 true
首次 process 一张图片,或切换图片。
首次使用分割。
首次使用动效。
首次使用美妆。

setEffect

设置美颜、美型、滤镜、美妆、贴纸、分割等效果,可在任意线程调用。具体参数请参见 美颜参数说明
void setEffect(String effectName, int effectValue, String resourcePath, Map<String, String> extraInfo)

setXmagicLogLevel

在 new XmagicApi() 之后调用。设置 SDK 的 log 等级,默认为Log.WARN。开发调试阶段如有需要,可以将其设为Log.DEBUG。正式发布时务必设置为Log.WARNLog.ERROR,否则大量的日志会影响性能。
如果设置了 ITELogger,则会把SDK内部的日志回调给使用者。
public void setXmagicLogLevel(int level);
public void setXmagicLogLevel(int level, final ITELogger logger);

public interface ITELogger{
void log(int severity, String tag, String msg);

void log(int severity, String tag, String msg, Throwable throwable);

}

enableHighPerformance

调用此方法开启高性能模式,V3.7.0新增。高性能模式开启后,美颜占用的系统 CPU/GPU 资源更少,可减少手机的发热和卡顿现象,更适合低端机长时间使用。但与常规模式相比,功能会少一些。
需要在 new XmagicApi() 之后立即调用。详细说明见 高性能模式使用指引
void enableHighPerformance()

setFeatureEnableDisable

开启或关闭某个能力,请按需使用。
void setFeatureEnableDisable(String featureName, boolean enable)
参数
含义
String featureName
原子能力名称
取值如下:
XmagicConstant.FeatureName.SEGMENTATION_SKIN 皮肤分割能力,开启后可使磨皮和美白区域更精准。
XmagicConstant.FeatureName.SEGMENTATION_FACE_BLOCK人脸遮挡检测能力,开启后可避免妆容画到遮挡物上。
XmagicConstant.FeatureName.WHITEN_ONLY_SKIN_AREA 美白仅对皮肤生效
XmagicConstant.FeatureName.SMART_BEAUTY 智能美颜(为男性、宝宝减淡美颜美妆效果)
XmagicConstant.FeatureName.ANIMOJI_52_EXPRESSION 人脸表情能力
XmagicConstant.FeatureName.BODY_3D_POINT 身体点位能力
XmagicConstant.FeatureName.HAND_DETECT 手势检测能力
boolean enable
true 表示开启此能力,false 表示关闭此能力
上述能力中,比较常用的是 SEGMENTATION_SKINSEGMENTATION_FACE_BLOCK,SDK会根据 getDeviceLevel 的值默认开启这两项能力。如果您需要手动开启,建议在 level ≥ 4 时,开启 SEGMENTATION_SKIN, 在 level ≥ 5时,开启 SEGMENTATION_FACE_BLOCK

setXmagicStreamType

设置输入数据类型,有相机数据和图片数据两类,默认是相机数据流。
void setXmagicStreamType(int type)
参数
含义
int type
数据源类型,有以下两种选择:
XmagicApi.PROCESS_TYPE_CAMERA_STREAM :相机数据源。
XmagicApi.PROCESS_TYPE_PICTURE_DATA:图片数据源。

setAIDataListener

public void setAIDataListener(final XmagicAIDataListener aiDataListener);

public interface OnAIDataListener {
void onFaceDataUpdated(List<TEFaceData> faceDataList);
void onBodyDataUpdated(List<TEBodyData> bodyDataList);
void onAIDataUpdated(String jsonString);
@Deprecated
void onHandDataUpdated(List<TEHandData> handDataList);
}

onFaceDataUpdated

SDK 开始 process 图像后就会有回调,识别到人脸时,回调 List<FaceData>,list 的 size 就是人脸个数。没有人脸时,回调一个空的 List。
TEFaceData 的定义如下,points 是人脸83点的坐标,每个点有x、y两个坐标值,因此 points 长度固定为166。每个点的坐标值的取值范围不是基于原始输入图,而是将原图的短边缩放到256之后得到的人脸坐标。
因此,这里的回调的数据,建议仅用于判断当面画面中是否有人脸、有几个人脸。如果需要更高精度的人脸点位,请使用onAIDataUpdated 回调的数据。
public class TEFaceData {
public float[] points;

public TEFaceData() {
}

public TEFaceData(float[] points) {
this.points = points;
}
}

onHandDataUpdated

已废弃接口,不会有数据回调。老版本 SDK 在设置了手势动效,且识别到手势时回调。
如果需要手势数据,请使用onAIDataUpdated回调的数据。

onBodyDataUpdated

设置了美体的属性并且识别到身体的时候回调,其他情况不回调。回调的是身体42点的坐标,坐标值基于输入图的宽高。如果某个点未检测到,则坐标值为0。





onAIDataUpdated

回调人脸、手势、身体3D的详细数据,通常需要使用特定的 Licence 才有数据。一份示例数据如下:
关于face_info的详细说明,请查看 人脸点位
关于hand_info的详细说明,请查看 手势识别
关于body_3d_info的详细说明,请查看 身体点位 Android身体点位 iOS
{
"face_info": [{
"expression_weights": [0.001172, 0, 0.029249, ... , 0.060041, 0],
"face_256_point": [211.844238, 673.247192, ... , 339.247925, 654.792603],
"face_256_visible": [0.163925, 0.14921, ... , 0.99887, 0.99887],
"face_3d_info": {
"pitch": -3.860844850540161,
"pitch_fixed": 2.1123428344726562,
"roll": -12.797032356262207,
"roll_fixed": 1.3187808990478516,
"transform": [
[0.8919625878334045, 0.2843534052371979, 0.3514907658100128, 0],
[-0.17628398537635803, 0.9346542954444885, -0.3087802827358246, 0],
[-0.41632509231567383, 0.21345829963684082, 0.88380366563797, 0],
[-0.020958196371793747, -0.04502145200967789, -0.6078543663024902, 1]
],
"yaw": 24.824481964111328,
"yaw_fixed": 25.02082061767578
},
"left_eye_high_vis_ratio": 0,
"left_eyebrow_high_vis_ratio": 0,
"mouth_high_vis_ratio": 1,
"out_of_screen": false,
"right_eye_high_vis_ratio": 1,
"right_eyebrow_high_vis_ratio": 0.821429,
"trace_id": 21
}],
"hand_info": {
"gesture": "PAPER",
"hand_point_2d": [180.71888732910156, 569.2958984375, ... , 353.8714294433594, 836.246826171875]
},
"body_3d_info": {
"imageHeight": 652,
"imageWidth": 320,
"items": [{
"index": 1,
"pose": [0.049122653901576996, ... , 0],
"position_x": [190.47494506835938, 235.23098754882812, ... , 4.948424339294434, 173.59298706054688],
"position_y": [777.2109375, 836.488037109375, ... , 161.19752502441406, 405.83905029296875],
"position_z": [0, 0, ... , 0, 0],
"rotation": [{
"data": [0.9944382905960083, -0.09695644676685333, -0.0411277711391449, 0.000708006089553237]
},
......
{
"data": [0.9907779693603516, 0.13549542427062988, 0, 0]
}, {
"data": [1, 0, 0, 0]
}]
}]
}
}

setAudioMute

动效素材使用时是否开启静音(V2.5.0新增):
参数:true 表示静音,false 表示非静音。

onPause

暂停特效里的声音播放,可与 Activity onPause 生命周期绑定。
void onPause()

onResume

恢复特效里的声音播放,可与 Activity onResume 生命周期绑定。
void onResume()

onDestroy

清理 GL 线程资源,需要在 GL 线程内调用。示例代码:
//示例代码见 TECameraBaseActivity.java
public void onGLContextDestroy() {
if (this.mXMagicApi != null) {
this.mXMagicApi.onDestroy();
this.mXMagicApi = null;
}
}

setImageOrientation

void setImageOrientation(TEImageOrientation orientation)

public enum TEImageOrientation {
ROTATION_0,
ROTATION_90,
ROTATION_180,
ROTATION_270
}
设置图像方向,使 AI 对不同朝向的人脸都能识别到,如果设置,则忽略sensorChanged传入的方向。方向示例如下:



如果您传给 SDK 的图像人物始终是正的(Rotation = 0),则无需调用此接口。

sensorChanged

void sensorChanged(android.hardware.SensorEvent event, android.hardware.Sensor accelerometer)
利用系统传感器判断当前手机旋转的角度,使 AI 对不同朝向的人脸都能识别到。注意:如果通过setImageOrientation设置了固定的方向,则会忽略sensorChagned传入的方向。
用法示例:
public class MyActivity implements SensorEventListener {
private SensorManager mSensorManager;
private Sensor mAccelerometer;
@Override
protected void onCreate(@Nullable Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
mSensorManager = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
mAccelerometer = mSensorManager.getDefaultSensor(Sensor.TYPE_ACCELEROMETER);
}
@Override
protected void onResume() {
super.onResume();
mSensorManager.registerListener(this, mAccelerometer, SensorManager.SENSOR_DELAY_NORMAL);
}
@Override
protected void onPause() {
super.onPause();
mSensorManager.unregisterListener(this);
}

@Override
public void onSensorChanged(SensorEvent event) {
if (mXMagicApi != null) {
mXMagicApi.sensorChanged(event, mAccelerometer);
}
}
}

isDeviceSupport

boolean isDeviceSupport(String motionResPath)
将一个动效素材的路径传给 SDK,检测当前设备是否完全支持这个动效。
例如一个动效里有口红、面部贴纸、背景分割,如果当前设备不支持背景分割,则此接口会返回 false。false 并不意味着该动效完全无法使用,而是部分效果无法呈现出来。

isSupportBeauty

判断当前机型是否支持美颜(OpenGL3.0),目前市场上绝大多数手机都是支持 OpenGL3.0的,所以通常无需使用此接口。
boolean isSupportBeauty()

exportCurrentTexture

获取当前纹理上的画面
void exportCurrentTexture(ExportTextureCallback callback)

public interface ExportTextureCallback {
void onCallback(Bitmap bitmap);
}

setTipsListener

设置动效提示语回调函数,用于将提示语展示到前端页面上。例如某些素材会提示用户点点头、伸出手掌、比心等。
注意:回调方法不一定在主线程
void setTipsListener(XmagicApi.XmagicTipsListener effectTipsListener)
XmagicTipsListener 包含如下方法:
public interface XmagicTipsListener {

/**
* 显示tips。
* @param tips 返回的提示语文本信息。
* @param tipsIcon tips的icon的文件路径,可根据文件路径解析出对应图片,pag文件的话需要使用pagView来展示。
* 注意:tipsIcon有可能为空,素材中没有配置就返回空值
* @param type tips类别,0表示tips和tipsIcon 都有值,1表示是pag素材只有tipsIcon有值。
* @param duration tips显示时长, 毫秒
*/
void tipsNeedShow(String tips, String tipsIcon, int type, int duration);

/***
* 隐藏tips。
* @param tips 返回的提示语文本信息。
* @param tipsIcon tips的icon的文件路径,可根据文件路径解析出对应图片,pag文件的话需要使用pagView来展示。
* 注意:tipsIcon有可能为空,素材中没有配置就返回空值
* @param type tips类别,0表示tips和tipsIcon 都有值,1表示是pag素材只有tipsIcon有值。
*/
void tipsNeedHide(String tips, String tipsIcon, int type);
}
示例代码如下:
public void tipsNeedShow(final String tips, String tipsIcon, int type, int duration) {
final int tipsType = type;
final String tipsIconPath = tipsIcon;
mMainThreadHandler.post(new Runnable() {
@Override
public void run() {
if (tipsType == 0) {
if (!TextUtils.isEmpty(tipsIconPath) && !mImageTipsIsShow) {
mTipsImageView.setVisibility(View.VISIBLE);
Bitmap bitmap = BitmapUtils.decodeSampleBitmap(AEModule.getContext(), tipsIconPath, Integer.MAX_VALUE, Integer.MAX_VALUE);
mTipsImageView.setImageBitmap(bitmap);
mImageTipsIsShow = true;
} else {
mTipsImageView.setVisibility(View.GONE);
}
mTipsTextView.setText(tips);
} else {
pagFile = PAGFile.Load(tipsIconPath);
tipsPAGView.post(new Runnable() {@
Override
public void run() {
if (pagFile != null) {
tipsPAGView.setRepeatCount(-1);
tipsPAGView.setComposition(pagFile);
tipsPAGView.setProgress(0);
tipsPAGView.play();
tipsPAGView.setVisibility(View.VISIBLE);
}
}
});
}
}
});
}
public void tipsNeedHide(String tips, String tipsIcon, int type) {
final int tipsType = type;
final String tipsIconPath = tipsIcon;
mMainThreadHandler.post(new Runnable() {
@Override
public void run() {
if (tipsType == 0) {
mTipsContainer.setVisibility(View.GONE);
mImageTipsIsShow = false;
} else {
tipsPAGView.post(new Runnable() {
@Override
public void run() {
tipsPAGView.stop();
tipsPAGView.setVisibility(View.GONE);
}
});
}
}
});
}

setSyncMode

SDK 内部有部分识别逻辑、渲染逻辑是异步处理的,调用此接口可以使 SDK 在接下来的 syncFrameCount 帧同步处理输入的图像,以满足某些场景特定的需求。例如首帧 process 前,调用该接口让 SDK 同步处理几帧,可以避免无美颜的画面展示出来,但这会导致首帧渲染前的黑屏时间变长,请按需使用。
void setSyncMode(boolean isSync, int syncFrameCount)
参数
含义
isSync
是否要同步处理图像帧。
syncFrameCount
需要同步处理的帧数,取值>=0,如果取值为-1,表示无限帧数。