实现 Android 美颜
集成 SDK
下载 SDK
前往 下载 页面,获取最新版的 SDK,然后解压。
添加依赖
将 SDK 包内 facebetter.aar 库,拷贝到你的项目路径下, 如 libs目录。
修改项目的 build.gradle 在 dependencies 部分添加 facebetter.aar 依赖, facebetter.aar的路径根据自己情况来配置
dependencies {
implementation files('libs/facebetter.aar')
implementation libs.appcompat
implementation libs.material
...
} 权限配置
在 AndroidManifest.xml 中添加必要权限:
<!-- 网络权限(必需):用于 appId 和 appKey 的联网验证 -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<!-- 存储权限(可选):仅在需要写日志文件时使用 -->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<!-- 相机权限(可选):仅在 demo 使用相机采集时才需要 -->
<uses-permission android:name="android.permission.CAMERA" />权限说明:
- 网络权限:必需。SDK 需要联网验证
appId和appKey,确保应用正常运行。 - 存储权限:可选。仅在配置了文件日志(
logConfig.fileEnabled = true)时需要。 - 相机权限:可选。仅在应用中使用相机采集图像进行美颜处理时需要,如果只处理已有图片不需要此权限。
导入类
Facebetter 引擎主要有四个类需要用到,需要导入到使用的文件中:
import com.pixpark.facebetter.BeautyEffectEngine;
import com.pixpark.facebetter.BeautyParams.*;
import com.pixpark.facebetter.ImageBuffer;
import com.pixpark.facebetter.ImageFrame;日志配置
默认日志是关闭的,可以按需开启,支持控制台日志和文件日志开关。开启日志要放到美颜引擎创建之前。
BeautyEffectEngine.LogConfig logConfig = new BeautyEffectEngine.LogConfig();
// 控制台日志
logConfig.consoleEnabled = true;
// 文件日志
logConfig.fileEnabled = true;
// 日志级别
logConfig.level = BeautyEffectEngine.LogLevel.INFO;
// 日志存储路径
logConfig.fileName = "xx/xx/facebetter.log";
BeautyEffectEngine.setLogConfig(logConfig);创建配置引擎
按照 此页面 指引,获取 appid 和 appkey
BeautyEffectEngine.EngineConfig config = new BeautyEffectEngine.EngineConfig();
config.appId = "your appId"; // 配置你的 appid
config.appKey = "your appkey"; // 配置你的 appkey
// 或者直接提供 licenseJson(可选,如果提供了则优先使用,不需要 appId 和 appKey)
// config.licenseJson = "your license json string";
mBeautyEngine = new BeautyEffectEngine(this, config);错误处理
创建引擎后建议检查是否成功:
if (mBeautyEngine == null) {
Log.e("BeautyEngine", "Failed to create beauty engine");
return;
}启用特效类型
美颜功能可以按类型开启关闭,根据订阅版本启用相应的美颜类型,每种类型还有对应的参数可以调节
// 美肤, 所有订阅版本都支持
int ret = mBeautyEngine.enableBeautyType(BeautyType.BASIC, true);
// 美型, Pro, Pro+ 版本支持
int ret = mBeautyEngine.enableBeautyType(BeautyType.RESHAPE, true);
// 美妆, Pro, Pro+ 版本支持
int ret = mBeautyEngine.enableBeautyType(BeautyType.MAKEUP, true);
// 虚拟背景, 仅 Pro+ 版本支持
int ret = mBeautyEngine.enableBeautyType(BeautyType.VIRTUAL_BACKGROUND, true);检查操作结果
所有 API 调用都应该检查返回值:
int ret = mBeautyEngine.enableBeautyType(BeautyType.BASIC, true);
if (ret == 0) {
Log.d("BeautyEngine", "Successfully enabled basic beauty");
} else {
Log.e("BeautyEngine", "Failed to enable basic beauty, error code: " + ret);
}调节美颜参数
设置美肤参数
通过 setBeautyParam 接口,设置美肤参数,参数范围 [0.0, 1.0];
float value = 0.5; // 取值范围[0.0, 1.0]
int ret = mBeautyEngine.setBeautyParam(BasicParam.SMOOTHING, value);支持的美肤参数:
public static enum BasicParam {
SMOOTHING(0), // 磨皮
SHARPENING(1), // 锐化
WHITENING(2), // 美白
ROSINESS(3); // 红润
}设置美型参数
通过 setBeautyParam 接口,设置美型参数,参数范围 [0.0, 1.0];
beautyEffectEngine.setBeautyParam(BeautyParams.ReshapeParam.FACE_THIN, 0.5f);支持的美型参数:
public enum ReshapeParam {
FACE_THIN(0), // 瘦脸
FACE_V_SHAPE(1), // V脸
FACE_NARROW(2), // 窄脸
FACE_SHORT(3), // 短脸
CHEEKBONE(4), // 颧骨
JAWBONE(5), // 下颌骨
CHIN(6), // 下巴
NOSE_SLIM(7), // 瘦鼻梁
EYE_SIZE(8), // 大眼
EYE_DISTANCE(9); // 眼距
}设置美妆参数
beautyEffectEngine.setBeautyParam(BeautyParams.MakeupParam.LIPSTICK, 0.5f);支持的美妆参数:
public enum MakeupParam {
LIPSTICK(0), // 口红
BLUSH(1); // 腮红
}设置虚拟背景
通过 enableBeautyType 接口启用虚拟背景:
beautyEffectEngine.enableBeautyType(BeautyParams.BeautyType.VIRTUAL_BACKGROUND, true);通过 setVirtualBackground 接口设置虚拟背景:
// 设置背景模式
BeautyParams.VirtualBackgroundOptions options = new BeautyParams.VirtualBackgroundOptions();
options.mode = BeautyParams.BackgroundMode.BLUR; // 模糊背景
beautyEffectEngine.setVirtualBackground(options);
// 设置背景图片(需要先设置为 IMAGE 模式)
BeautyParams.VirtualBackgroundOptions imageOptions = new BeautyParams.VirtualBackgroundOptions();
imageOptions.mode = BeautyParams.BackgroundMode.IMAGE;
imageOptions.backgroundImage = imageFrame; // ImageFrame 对象
beautyEffectEngine.setVirtualBackground(imageOptions);处理图像
创建图像
图像数据通过 ImageFrame 封装,支持格式: I420, NV12, NV21, RGB, RGBA, BGR, BGRA
通过 RGBA 创建 ImageFrame
ByteBuffer data = ByteBuffer.allocateDirect(width * height * 4);
ImageFrame inputImage = ImageFrame.createWithRGBA(data, width, height, stride);通过图片创建 ImageFrame
ImageFrame inputImage = ImageFrame.createWithFile("xxx.png");旋转图像
ImageFrame 内置图像旋转方法, 可根据需要使用
int result = inputImage.rotate(ImageBuffer.Rotation.ROTATION_90);旋转角度
public enum Rotation {
ROTATION_0(0), // 0度
ROTATION_90(1), // 顺时针旋转90度
ROTATION_180(2), // 顺时针旋转180度
ROTATION_270(3); // 顺时针旋转270度
}处理图像
processMode 包括 VIDEO 和 IMAGE 两种,VIDEO 适合直播,视频等场景使用,效率更高,IMAGE 模式适合图片处理场景
ImageFrame outputImage = beautyEffectEngine.processImage(inputImage, BeautyEffectEngine.ProcessMode.VIDEO);获取处理后图像数据
ImageFrame 可以通过 ImageBuffer 获取处理后的图像数据, 如 RGBA
ImageBuffer buffer = outputImage.toRGBA();
ByteBuffer data = buffer.getData();
int dataSize = buffer.getSize();
int width = buffer.getWidth();
int height = buffer.getHeight();
int stride = buffer.getStride();获取 I420 数据
ImageBuffer buffer = outputImage.toI420();
// 获取连续的 I420 内存数据
ByteBuffer data = buffer.getData();
// 整个 I420 数据长度
int dataSize = buffer.getSize();
// 独立获取 Y, U, V 分量数据
ByteBuffer dataY = buffer.getDataY();
ByteBuffer dataU = buffer.getDataU();
ByteBuffer dataV = buffer.getDataV();
int strideY = buffer.getStrideY();
int strideU = buffer.getStrideU();
int strideV = buffer.getStrideV();ImageFrame 通过内置方法 toXXX 可以转化为各种格式: I420, NV12, NV21, RGB, RGBA, BGR, BGRA. 可以借助这些方法完成格式转换。
生命周期管理
释放资源
在 Activity 或 Fragment 销毁时,务必释放引擎资源:
@Override
protected void onDestroy() {
super.onDestroy();
if (mBeautyEngine != null) {
mBeautyEngine.release();
mBeautyEngine = null;
}
}内存管理
- 及时释放
ImageFrame和ImageBuffer对象 - 避免在循环中重复创建大量图像对象
- 建议复用
ImageFrame对象
// 使用完毕后释放资源
if (inputImage != null) {
inputImage.release();
}
if (outputImage != null) {
outputImage.release();
}
if (buffer != null) {
buffer.release();
}