补充美颜模型和美颜配置

This commit is contained in:
2022-09-19 15:43:06 +08:00
parent 8ef917ebb6
commit c634d29e79
365 changed files with 5751 additions and 1296 deletions

View File

@@ -0,0 +1,166 @@
package com.yunbao.faceunity.data;
import com.faceunity.core.entity.FUBundleData;
import com.faceunity.core.enumeration.FUAITypeEnum;
import com.faceunity.core.faceunity.FUAIKit;
import com.faceunity.core.faceunity.FURenderKit;
import com.faceunity.core.model.animationFilter.AnimationFilter;
import com.faceunity.core.model.antialiasing.Antialiasing;
import com.faceunity.core.model.prop.Prop;
import com.faceunity.core.model.prop.PropContainer;
import com.faceunity.core.model.prop.animoji.Animoji;
import com.yunbao.faceunity.entity.AnimationFilterBean;
import com.yunbao.faceunity.entity.AnimojiBean;
import com.yunbao.faceunity.infe.AbstractAnimojiDataFactory;
import com.yunbao.faceunity.repo.AnimojiSource;
import com.yunbao.faceunity.utils.FaceUnityConfig;
import java.util.ArrayList;
/**
* DESCAnimoji业务工厂
* Created on 2021/3/3
*/
public class AnimojiDataFactory extends AbstractAnimojiDataFactory {
/*渲染控制器*/
private FURenderKit mFURenderKit = FURenderKit.getInstance();
private FUAIKit mFUAIKit = FUAIKit.getInstance();
/*3D抗锯齿*/
public final Antialiasing antialiasing;
/*动漫滤镜模型*/
public final AnimationFilter animationFilter;
/*当前选中贴图模型*/
private Prop currentAnimoji;
/*当前选中下标*/
private int currentAnimojiIndex;
/*当前滤镜下标*/
private int currentFilterIndex;
/*Animoji数据*/
private ArrayList<AnimojiBean> animojiBeans;
/*Animoji滤镜数据*/
private ArrayList<AnimationFilterBean> animationFilterBeans;
/**
* 构造 AnimojiDataFactory
*
* @param animojiIndex 贴图下标
* @param filterIndex 滤镜下标
*/
public AnimojiDataFactory(int animojiIndex, int filterIndex) {
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
animationFilter = new AnimationFilter(new FUBundleData(FaceUnityConfig.BUNDLE_ANIMATION_FILTER));
currentAnimojiIndex = animojiIndex;
currentFilterIndex = filterIndex;
animojiBeans = AnimojiSource.buildAnimojis();
animationFilterBeans = AnimojiSource.buildFilters();
}
/**
* 动漫贴图列表
*
* @return
*/
@Override
public ArrayList<AnimojiBean> getAnimojis() {
return animojiBeans;
}
/**
* 动漫滤镜列表
*
* @return
*/
@Override
public ArrayList<AnimationFilterBean> getFilters() {
return animationFilterBeans;
}
/**
* 当前选中动漫贴图下标
*
* @return
*/
@Override
public int getCurrentAnimojiIndex() {
return currentAnimojiIndex;
}
/**
* 设置当前选中动漫贴图下标
*
* @return
*/
@Override
public void setCurrentAnimojiIndex(int currentAnimojiIndex) {
this.currentAnimojiIndex = currentAnimojiIndex;
}
/**
* 当前选中滤镜下标
*
* @return
*/
@Override
public int getCurrentFilterIndex() {
return currentFilterIndex;
}
/**
* 设置当前选中动漫贴图下标
*
* @return
*/
@Override
public void setCurrentFilterIndex(int currentFilterIndex) {
this.currentFilterIndex = currentFilterIndex;
}
/**
* 设置选中贴图
*
* @param bean
*/
@Override
public void onAnimojiSelected(AnimojiBean bean) {
PropContainer propContainer = mFURenderKit.getPropContainer();
String path = bean.getPath();
Prop prop = null;
if (path != null && path.trim().length() > 0) {
prop = new Animoji(new FUBundleData(path));
}
propContainer.replaceProp(currentAnimoji, prop);
currentAnimoji = prop;
}
/**
* 设置选中滤镜
*
* @param data
*/
@Override
public void onFilterSelected(AnimationFilterBean data) {
animationFilter.setStyle(data.getStyle());
}
/**
* FURenderKit加载当前特效
*/
public void bindCurrentRenderer() {
mFUAIKit.loadAIProcessor(FaceUnityConfig.BUNDLE_AI_TONGUE, FUAITypeEnum.FUAITYPE_TONGUETRACKING);
mFUAIKit.setMaxFaces(4);
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
mFURenderKit.setAntialiasing(antialiasing);
mFURenderKit.setAnimationFilter(animationFilter);
animationFilter.setStyle(animationFilterBeans.get(currentFilterIndex).getStyle());
onAnimojiSelected(animojiBeans.get(currentAnimojiIndex));
}
/**
* 结束需要释放AI驱动
*/
public void releaseAIProcessor() {
mFUAIKit.releaseAIProcessor(FUAITypeEnum.FUAITYPE_TONGUETRACKING);
}
}

View File

@@ -0,0 +1,158 @@
package com.yunbao.faceunity.data;
import com.faceunity.core.avatar.model.Avatar;
import com.faceunity.core.avatar.model.Scene;
import com.faceunity.core.avatar.scene.ProcessorConfig;
import com.faceunity.core.entity.FUBundleData;
import com.faceunity.core.entity.FUCoordinate3DData;
import com.faceunity.core.enumeration.FUAITypeEnum;
import com.faceunity.core.faceunity.FUAIKit;
import com.faceunity.core.faceunity.FURenderKit;
import com.faceunity.core.faceunity.FUSceneKit;
import com.faceunity.core.model.antialiasing.Antialiasing;
import com.yunbao.faceunity.entity.AvatarBean;
import com.yunbao.faceunity.infe.AbstractAvatarDataFactory;
import com.yunbao.faceunity.repo.AvatarSource;
import com.yunbao.faceunity.utils.FaceUnityConfig;
import java.util.ArrayList;
/**
* DESC
* Created on 2021/3/30
*/
public class AvatarDataFactory extends AbstractAvatarDataFactory {
/*渲染控制器*/
private FURenderKit mFURenderKit = FURenderKit.getInstance();
private FUAIKit mFUAIKit = FUAIKit.getInstance();
/*3D抗锯齿*/
public final Antialiasing antialiasing;
/* 人物队列 */
private ArrayList<AvatarBean> members;
/* 当前选中人物下标 */
private int currentMemberIndex;
/* 驱动类型是否为全身 */
private Boolean isHumanTrackSceneFull;
/* 场景 */
private Scene sceneModel;
/* 男孩对象 */
private Avatar boyAvatarModel;
/* 女孩对象 */
private Avatar girlAvatarModel;
/*当前对象*/
private Avatar currentAvatarModel;
public AvatarDataFactory(int index, boolean isFull) {
isHumanTrackSceneFull = isFull;
currentMemberIndex = index;
members = AvatarSource.buildMembers();
antialiasing = new Antialiasing(new FUBundleData(FaceUnityConfig.BUNDLE_ANTI_ALIASING));
boyAvatarModel = AvatarSource.buildBoyData(isFull);
girlAvatarModel = AvatarSource.buildGirlData(isFull);
if (index == 0) {
currentAvatarModel = girlAvatarModel;
} else if (index == 1) {
currentAvatarModel = boyAvatarModel;
}
sceneModel = AvatarSource.buildSceneModel(currentAvatarModel);
AvatarSource.setSceneBackGround(sceneModel, true);
}
/**
* 获取人物队列
*
* @return
*/
@Override
public ArrayList<AvatarBean> getMembers() {
return members;
}
/**
* 获取当前选中人物下标
*
* @return
*/
@Override
public int getCurrentMemberIndex() {
return currentMemberIndex;
}
/**
* 设置当前人物选中下标
*
* @param index
*/
@Override
public void setCurrentMemberIndex(int index) {
currentMemberIndex = index;
}
/**
* 获取当前驱动类型
*
* @return
*/
@Override
public boolean isHumanTrackSceneFull() {
return isHumanTrackSceneFull;
}
/**
* 设置当前驱动类型
*
* @param isFull
*/
@Override
public void setHumanTrackSceneFull(boolean isFull) {
isHumanTrackSceneFull = isFull;
sceneModel.processorConfig.setTrackScene(isFull ? ProcessorConfig.TrackScene.SceneFull : ProcessorConfig.TrackScene.SceneHalf);
if (isFull) {
boyAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 58.14, -618.94));
girlAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 58.14, -618.94));
} else {
boyAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 11.76, -183.89));
girlAvatarModel.transForm.setPosition(new FUCoordinate3DData(0.0, 11.76, -183.89));
}
}
/**
* 人物切换
*
* @param bean
*/
@Override
public void onMemberSelected(AvatarBean bean) {
if (mAvatarChoiceListener != null)
mAvatarChoiceListener.choiceAvatar(bean);
sceneModel.replaceAvatar(currentAvatarModel, bean.getDes().equals(AvatarSource.GIRL) ? girlAvatarModel : boyAvatarModel);
currentAvatarModel = bean.getDes().equals(AvatarSource.GIRL) ? girlAvatarModel : boyAvatarModel;
}
public void bindCurrentRenderer() {
mFUAIKit.loadAIProcessor(FaceUnityConfig.getAIHumanBundle(), FUAITypeEnum.FUAITYPE_HUMAN_PROCESSOR);
mFUAIKit.setMaxFaces(1);
mFURenderKit.setAntialiasing(antialiasing);
FUSceneKit.getInstance().addSceneGL(sceneModel);
FUSceneKit.getInstance().setCurrentSceneGL(sceneModel);
setHumanTrackSceneFull(isHumanTrackSceneFull);
}
public AvatarChoiceListener mAvatarChoiceListener;
public interface AvatarChoiceListener {
void choiceAvatar(AvatarBean avatarBean);
}
public void setAvatarChoiceListener(AvatarChoiceListener avatarChoiceListener) {
this.mAvatarChoiceListener = avatarChoiceListener;
}
}

View File

@@ -0,0 +1,347 @@
package com.yunbao.faceunity.data;
import androidx.annotation.NonNull;
import com.faceunity.core.controller.bgSegGreen.BgSegGreenParam;
import com.faceunity.core.entity.FUColorRGBData;
import com.faceunity.core.faceunity.FUAIKit;
import com.faceunity.core.faceunity.FURenderKit;
import com.faceunity.core.model.bgSegGreen.BgSegGreen;
import com.yunbao.faceunity.entity.BgSegGreenBackgroundBean;
import com.yunbao.faceunity.entity.BgSegGreenBean;
import com.yunbao.faceunity.entity.BgSegGreenSafeAreaBean;
import com.yunbao.faceunity.entity.ModelAttributeData;
import com.yunbao.faceunity.infe.AbstractBgSegGreenDataFactory;
import com.yunbao.faceunity.repo.BgSegGreenSource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Objects;
/**
* DESC绿幕抠像业务工厂
* Created on 2021/3/4
*/
public class BgSegGreenDataFactory extends AbstractBgSegGreenDataFactory {
public interface BgSegGreenListener {
/**
* 取色状态回调
*
* @param isSelected 是否选中
* @param color 默认颜色
*/
void onColorPickerStateChanged(boolean isSelected, int color);
/**
* 切换背景道具
*
* @param bean
*/
void onBackgroundSelected(BgSegGreenBackgroundBean bean);
/**
* 添加自定义安全区域图片
*/
void onSafeAreaAdd();
/**
* 切换安全区域图片
*
* @param bean
*/
void onSafeAreaSelected(BgSegGreenSafeAreaBean bean);
}
/*渲染控制器*/
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
/*绿幕抠像特效模型*/
private final BgSegGreen mBgSegGreen;
/*绿幕抠像背景列表*/
private final ArrayList<BgSegGreenBackgroundBean> mBgSegGreenBackgroundBeans;
/* 绿幕抠像当前背景下标 */
private int mCurrentBackgroundIndex;
/*绿幕抠像安全区域列表*/
private ArrayList<BgSegGreenSafeAreaBean> mBgSegGreenSafeAreaBeans;
/* 绿幕抠像当前安全区域下标 */
private int mCurrentSafeAreaIndex;
/* 回调 */
private final BgSegGreenListener mBgSegGreenListener;
/**
* 构造绿幕抠像
*
* @param listener 回调
* @param index 背景下标
*/
public BgSegGreenDataFactory(BgSegGreenListener listener, int index) {
mBgSegGreenListener = listener;
mBgSegGreen = BgSegGreenSource.buildBgSegGreen();
mBgSegGreenBackgroundBeans = BgSegGreenSource.buildBgSegGreenBackground();
mBgSegGreenSafeAreaBeans = BgSegGreenSource.buildBgSegGreenSafeArea();
mCurrentBackgroundIndex = index;
mCurrentSafeAreaIndex = 1;
}
/**
* 获取绿幕抠像当前背景下标
*
* @return
*/
@Override
public int getBackgroundIndex() {
return mCurrentBackgroundIndex;
}
/**
* 设置绿幕抠像当前背景下标
*
* @param backgroundIndex
*/
@Override
public void setBackgroundIndex(int backgroundIndex) {
this.mCurrentBackgroundIndex = backgroundIndex;
}
/**
* 获取绿幕抠像当前安全区域下标
*
* @return
*/
@Override
public int getBgSafeAreaIndex() {
return mCurrentSafeAreaIndex;
}
/**
* 设置绿幕抠像安全区域下标
*
* @param currentSafeAreaIndex
*/
@Override
public void setBgSafeAreaIndex(int currentSafeAreaIndex) {
this.mCurrentSafeAreaIndex = currentSafeAreaIndex;
}
/**
* 更新安全区UI
*/
public boolean updateSafeAreaBeansAndIndex() {
ArrayList<BgSegGreenSafeAreaBean> bgSegGreenSafeAreaBeans = BgSegGreenSource.buildBgSegGreenSafeArea();
if (!bgSegGreenSafeAreaBeans.equals(mBgSegGreenSafeAreaBeans)) {
//需要刷新数据
//比对数据 1、数据增加 or 自定义数据修改 -> 当前应该选中的角标
if (bgSegGreenSafeAreaBeans.size() > mBgSegGreenSafeAreaBeans.size()) {
//数据增加
if (mCurrentSafeAreaIndex > 2) {
mCurrentSafeAreaIndex++;
}
}
mBgSegGreenSafeAreaBeans = bgSegGreenSafeAreaBeans;
return true;
}
return false;
}
/**
* 获取绿幕抠像项目数据扩展模型
*
* @return
*/
@Override
public HashMap<String, ModelAttributeData> getModelAttributeRange() {
return BgSegGreenSource.buildModelAttributeRange();
}
/**
* 获取绿幕抠像功能列表
*
* @return
*/
@Override
public ArrayList<BgSegGreenBean> getBgSegGreenActions() {
return BgSegGreenSource.buildBgSegGreenAction();
}
/**
* 获取绿幕抠像安全区域功能列表
*
* @return
*/
@Override
public ArrayList<BgSegGreenSafeAreaBean> getBgSegGreenSafeAreas() {
return mBgSegGreenSafeAreaBeans;
}
/**
* 获取绿幕抠像背景列表
*
* @return
*/
@Override
public ArrayList<BgSegGreenBackgroundBean> getBgSegGreenBackgrounds() {
return mBgSegGreenBackgroundBeans;
}
/**
* 背景图片变更
*
* @param data BgSegGreenBackgroundBean
*/
@Override
public void onBackgroundSelected(BgSegGreenBackgroundBean data) {
mBgSegGreenListener.onBackgroundSelected(data);
}
/**
* 自定义安全区域
*/
@Override
public void onSafeAreaAdd() {
mBgSegGreenListener.onSafeAreaAdd();
}
/**
* 安全区域变更
*
* @param data BgSegGreenBackgroundBean
*/
@Override
public void onSafeAreaSelected(BgSegGreenSafeAreaBean data) {
mBgSegGreenListener.onSafeAreaSelected(data);
}
@Override
public boolean isUseTemplate() {
return getCurrentBgSegGreenModel().isUseTemplate() == 1.0;
}
/**
* 取色锚点颜色变更
*
* @param array DoubleArray
*/
@Override
public void onColorRGBChanged(double[] array) {
mBgSegGreen.setColorRGB(new FUColorRGBData(array[0], array[1], array[2]));
mBgSegGreen.setEnable(true);
}
/**
* 绿幕开关
*
* @param enable Boolean
*/
@Override
public void onBgSegGreenEnableChanged(boolean enable) {
mBgSegGreen.setEnable(enable);
}
/**
* 根据名称标识获取对应的值
*
* @param key String 标识
* @return Double 值
*/
@Override
public double getParamIntensity(@NonNull String key) {
if (bgSegGreenGetMapping.containsKey(key)) {
return bgSegGreenGetMapping.get(key).getValue();
}
return 0.0;
}
/**
* 根据名称标识更新对应的值
*
* @param key String 标识
* @return Double 值
*/
@Override
public void updateParamIntensity(@NonNull String key, double value) {
if (bgSegGreenSetMapping.containsKey(key)) {
Objects.requireNonNull(bgSegGreenSetMapping.get(key)).setValue(value);
}
}
/**
* 调用取色器功能状态变更
*
* @param selected
* @param color
*/
@Override
public void onColorPickerStateChanged(boolean selected, int color) {
mBgSegGreenListener.onColorPickerStateChanged(selected, color);
}
//region 业务映射
/**
* 参数设置
*/
interface BgSegGreenSetParam {
void setValue(double value);
}
/**
* 模型参数获取
*/
interface BgSegGreenGetParam {
double getValue();
}
/**
* 获取当前绿幕对象
*
* @return
*/
private BgSegGreen getCurrentBgSegGreenModel() {
return mBgSegGreen;
}
/* 模型映射 */
private final HashMap<String, BgSegGreenSetParam> bgSegGreenSetMapping = new HashMap<String, BgSegGreenSetParam>() {
{
put(BgSegGreenParam.SIMILARITY, value -> getCurrentBgSegGreenModel().setSimilarity(value));
put(BgSegGreenParam.SMOOTHNESS, value -> getCurrentBgSegGreenModel().setSmoothness(value));
put(BgSegGreenParam.TRANSPARENCY, value -> getCurrentBgSegGreenModel().setTransparency(value));
}
};
/*模型映射获取模型值*/
private final HashMap<String, BgSegGreenGetParam> bgSegGreenGetMapping = new HashMap<String, BgSegGreenGetParam>() {
{
put(BgSegGreenParam.SIMILARITY, () -> getCurrentBgSegGreenModel().getSimilarity());
put(BgSegGreenParam.SMOOTHNESS, () -> getCurrentBgSegGreenModel().getSmoothness());
put(BgSegGreenParam.TRANSPARENCY, () -> getCurrentBgSegGreenModel().getTransparency());
}
};
//endregion 业务映射
/**
* FURenderKit加载当前特效
*/
public void bindCurrentRenderer() {
FUAIKit.getInstance().setMaxFaces(1);
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
mFURenderKit.setBgSegGreen(mBgSegGreen);
mBgSegGreenListener.onBackgroundSelected(mBgSegGreenBackgroundBeans.get(mCurrentBackgroundIndex));
mBgSegGreenListener.onSafeAreaSelected(mBgSegGreenSafeAreaBeans.get(mCurrentSafeAreaIndex));
}
}

View File

@@ -0,0 +1,101 @@
package com.yunbao.faceunity.data;
import com.faceunity.core.model.facebeauty.FaceBeautyBlurTypeEnum;
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
import java.io.Serializable;
import java.util.HashMap;
/**
* 保存到磁盘的对象
* 该例只保存特效demo展示出来的美颜功能
*/
public class FaceBeautyData implements Serializable {
/* 美肤 */
/* 磨皮类型 */
public int blurType = FaceBeautyBlurTypeEnum.FineSkin;
/* 磨皮程度 */
public double blurIntensity = 0.0;
/* 美白程度 */
public double colorIntensity = 0.0;
/* 红润程度 */
public double redIntensity = 0.0;
/* 锐化程度 */
public double sharpenIntensity = 0.0;
/* 亮眼程度 */
public double eyeBrightIntensity = 0.0;
/* 美牙程度 */
public double toothIntensity = 0.0;
/* 去黑眼圈强度*/
public double removePouchIntensity = 0.0;
/* 去法令纹强度*/
public double removeLawPatternIntensity = 0.0;
/*美型*/
/* 瘦脸程度 */
public double cheekThinningIntensity = 0.0;
/* V脸程度 */
public double cheekVIntensity = 0.0;
/* 窄脸程度 */
public double cheekNarrowIntensity = 0.0;
/* 短脸程度 */
public double cheekShortIntensity = 0.0;
/* 小脸程度 */
public double cheekSmallIntensity = 0.0;
/* 瘦颧骨 */
public double cheekBonesIntensity = 0.0;
/* 瘦下颌骨 */
public double lowerJawIntensity = 0.0;
/* 大眼程度 */
public double eyeEnlargingIntensity = 0.0;
/* 圆眼程度 */
public double eyeCircleIntensity = 0.0;
/* 下巴调整程度 */
public double chinIntensity = 0.5;
/* 额头调整程度 */
public double forHeadIntensity = 0.5;
/* 瘦鼻程度 */
public double noseIntensity = 0.0;
/* 嘴巴调整程度 */
public double mouthIntensity = 0.5;
/* 开眼角强度 */
public double canthusIntensity = 0.0;
/* 眼睛间距 */
public double eyeSpaceIntensity = 0.5;
/* 眼睛角度 */
public double eyeRotateIntensity = 0.5;
/* 鼻子长度 */
public double longNoseIntensity = 0.5;
/* 调节人中 */
public double philtrumIntensity = 0.5;
/* 微笑嘴角强度 */
public double smileIntensity = 0.0;
/* 眉毛上下 */
public double browHeightIntensity = 0.5;
/* 眉毛间距 */
public double browSpaceIntensity = 0.5;
/* 眼睑 */
public double eyeLidIntensity = 0.0;
/* 眼睛高度 */
public double eyeHeightIntensity = 0.5;
/* 眉毛粗细 */
public double browThickIntensity = 0.5;
/* 嘴巴厚度 */
public double lipThickIntensity = 0.5;
/* 五官立体 */
public double faceThreeIntensity = 0.5;
/* 风格推荐 */
/* 是否开启风格推荐 */
/* 风格推荐类型 */
public int styleTypeIndex = -1;
//所有滤镜
public HashMap<String,Double> filterMap = new HashMap<>();
/* 滤镜相关 */
/* 滤镜名称 */
public String filterName = FaceBeautyFilterEnum.ORIGIN;
/* 滤镜程度 */
public double filterIntensity = 0.0f;
}

View File

@@ -4,13 +4,20 @@ package com.yunbao.faceunity.data;
import androidx.annotation.NonNull;
import com.faceunity.core.controller.facebeauty.FaceBeautyParam;
import com.faceunity.core.entity.FUBundleData;
import com.faceunity.core.enumeration.FUAITypeEnum;
import com.faceunity.core.faceunity.FUAIKit;
import com.faceunity.core.faceunity.FURenderKit;
import com.faceunity.core.model.facebeauty.FaceBeauty;
import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum;
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
import com.yunbao.faceunity.entity.FaceBeautyBean;
import com.yunbao.faceunity.entity.FaceBeautyFilterBean;
import com.yunbao.faceunity.entity.FaceBeautyStyleBean;
import com.yunbao.faceunity.entity.ModelAttributeData;
import com.yunbao.faceunity.infe.AbstractFaceBeautyDataFactory;
import com.yunbao.faceunity.repo.FaceBeautySource;
import com.yunbao.faceunity.utils.FaceUnityConfig;
import java.util.ArrayList;
import java.util.HashMap;
@@ -22,6 +29,21 @@ import java.util.HashMap;
*/
public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
public interface FaceBeautyListener {
/**
* 风格切换
*
* @param res
*/
void onFilterSelected(int res);
/**
* 美颜开关
*
* @param enable
*/
void onFaceBeautyEnable(boolean enable);
}
interface FaceBeautySetParamInterface {
/**
@@ -44,11 +66,26 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
/*渲染控制器*/
private FURenderKit mFURenderKit = FURenderKit.getInstance();
/*当前生效美颜数据模型*/
public FaceBeauty defaultFaceBeauty = FaceBeautySource.getDefaultFaceBeauty();
/*推荐风格标识*/
private static int currentStyleIndex = -1;
/*美颜缓存数据模型 用于普通美颜*/
public static final FaceBeauty defaultFaceBeauty = FaceBeautySource.getDefaultFaceBeauty();
/*当前生效美颜数据模型 普通 or 风格的*/
public static FaceBeauty faceBeauty = defaultFaceBeauty;
/*默认滤镜选中下标*/
private int currentFilterIndex = 0;
/*业务回调*/
private final FaceBeautyListener mFaceBeautyListener;
public FaceBeautyDataFactory(FaceBeautyListener listener) {
mFaceBeautyListener = listener;
}
/**
* 获取美肤参数列表
@@ -72,6 +109,17 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
return FaceBeautySource.buildShapeParams();
}
/**
* 获取美型参数列表
*
* @return
*/
@NonNull
@Override
public ArrayList<FaceBeautyBean> getShapeBeautySubItem() {
return FaceBeautySource.buildFaceShapeSubItemParams();
}
/**
* 获取美肤、美型扩展参数
@@ -99,7 +147,6 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
filterBeans.get(i).setIntensity(defaultFaceBeauty.getFilterIntensity());
currentFilterIndex = i;
}
}
return filterBeans;
}
@@ -124,6 +171,46 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
this.currentFilterIndex = currentFilterIndex;
}
/**
* 获取推荐风格列表
*
* @return
*/
@NonNull
@Override
public ArrayList<FaceBeautyStyleBean> getBeautyStyles() {
return FaceBeautySource.buildStylesParams();
}
/**
* 获取当前风格推荐标识
*
* @return
*/
@Override
public int getCurrentStyleIndex() {
return currentStyleIndex;
}
/**
* 设置风格推荐标识
*
* @param styleIndex
*/
@Override
public void setCurrentStyleIndex(int styleIndex) {
currentStyleIndex = styleIndex;
}
/**
* 设置风格推荐标识 来自于硬盘
*
* @param styleIndex
*/
public static void setDiskCurrentStyleIndex(int styleIndex) {
currentStyleIndex = styleIndex;
}
/**
* 美颜开关设置
@@ -132,9 +219,7 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
*/
@Override
public void enableFaceBeauty(boolean enable) {
if (mFURenderKit.getFaceBeauty() != null) {
mFURenderKit.getFaceBeauty().setEnable(enable);
}
mFaceBeautyListener.onFaceBeautyEnable(enable);
}
/**
@@ -164,6 +249,69 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
}
}
/**
* 将所有效果制空
*/
@Override
public void resetParamIntensity() {
if (faceBeauty != defaultFaceBeauty) {
faceBeauty = defaultFaceBeauty;
FURenderKit.getInstance().setFaceBeauty(faceBeauty);
}
ArrayList<FaceBeautyBean> skinBeauty = getSkinBeauty();
ArrayList<FaceBeautyBean> shapeBeauty = getShapeBeauty();
HashMap<String, ModelAttributeData> modelAttributeRange = getModelAttributeRange();
//还原美肤
for (FaceBeautyBean faceBeautyBean : skinBeauty) {
String key = faceBeautyBean.getKey();
ModelAttributeData modelAttributeData = modelAttributeRange.get(key);
updateParamIntensity(key, modelAttributeData.getStand());
}
//还原美型
for (FaceBeautyBean faceBeautyBean : shapeBeauty) {
String key = faceBeautyBean.getKey();
ModelAttributeData modelAttributeData = modelAttributeRange.get(key);
updateParamIntensity(key, modelAttributeData.getStand());
}
//还原滤镜
defaultFaceBeauty.setFilterName(FaceBeautyFilterEnum.ORIGIN);
defaultFaceBeauty.setFilterIntensity(0.0);
setCurrentFilterIndex(0);
//设置风格角标
setCurrentStyleIndex(-1);
}
@Override
public String getCurrentOneHotFaceShape() {
return CurrentFaceShapeUIValue.currentFaceShape == null ? FaceBeautyParam.CHEEK_V_INTENSITY : CurrentFaceShapeUIValue.currentFaceShape;
}
@Override
public void setCurrentOneHotFaceShape(String faceShape) {
CurrentFaceShapeUIValue.currentFaceShape = faceShape;
}
/**
* 设置当前脸型的UI值
*/
public void setCurrentFaceShapeUIValue(HashMap<String, Double> hashMap) {
CurrentFaceShapeUIValue.currentFaceShapeValue.clear();
CurrentFaceShapeUIValue.currentFaceShapeValue.putAll(hashMap);
}
/**
* 获取当前脸型的UI值
*/
public HashMap<String, Double> getCurrentFaceShapeUIValue() {
return CurrentFaceShapeUIValue.currentFaceShapeValue;
}
/**
* 切换滤镜
*
@@ -175,6 +323,7 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
public void onFilterSelected(@NonNull String name, double intensity, int resID) {
defaultFaceBeauty.setFilterName(name);
defaultFaceBeauty.setFilterIntensity(intensity);
mFaceBeautyListener.onFilterSelected(resID);
}
/**
@@ -187,6 +336,23 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
defaultFaceBeauty.setFilterIntensity(intensity);
}
/**
* 设置推荐风格
*
* @param name
*/
@Override
public void onStyleSelected(String name) {
if (name == null) {
faceBeauty = defaultFaceBeauty;
FURenderKit.getInstance().setFaceBeauty(faceBeauty);
} else {
Runnable runnable = FaceBeautySource.styleParams.get(name);
if (runnable != null) {
runnable.run();
}
}
}
/*模型映射设置模型值*/
private final HashMap<String, FaceBeautySetParamInterface> faceBeautySetMapping = new HashMap<String, FaceBeautySetParamInterface>() {{
@@ -270,6 +436,22 @@ public class FaceBeautyDataFactory extends AbstractFaceBeautyDataFactory {
* FURenderKit加载当前特效
*/
public void bindCurrentRenderer() {
mFURenderKit.setFaceBeauty(defaultFaceBeauty);
mFURenderKit.setFaceBeauty(faceBeauty);
FUAIKit.getInstance().setMaxFaces(4);
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
mFURenderKit.getPropContainer().addProp(expressionRecognition);
}
}
/**
* 用于记录当前脸型的UI值 -> 用于用户下次点入的时候恢复
*/
static class CurrentFaceShapeUIValue {
/* 当前生效的脸型 */
public static String currentFaceShape = FaceBeautyParam.CHEEK_V_INTENSITY;
/* 当前脸型的UI值 */
public static HashMap<String, Double> currentFaceShapeValue = new HashMap<>();
}
}

View File

@@ -2,6 +2,7 @@ package com.yunbao.faceunity.data;
import com.faceunity.core.enumeration.FUAIProcessorEnum;
import com.faceunity.core.faceunity.FURenderKit;
import com.yunbao.faceunity.entity.PropBean;
import com.yunbao.faceunity.utils.FURenderer;
/**
@@ -50,10 +51,25 @@ public class FaceUnityDataFactory {
public FaceUnityDataFactory(int index) {
currentFunctionIndex = index;
mFaceBeautyDataFactory = new FaceBeautyDataFactory();
mFaceBeautyDataFactory = new FaceBeautyDataFactory(new FaceBeautyDataFactory.FaceBeautyListener() {
@Override
public void onFilterSelected(int res) {
}
@Override
public void onFaceBeautyEnable(boolean enable) {
}
});
mBodyBeautyDataFactory = new BodyBeautyDataFactory();
mMakeupDataFactory = new MakeupDataFactory(0);
mPropDataFactory = new PropDataFactory(0);
mPropDataFactory = new PropDataFactory(new PropDataFactory.PropListener() {
@Override
public void onItemSelected(PropBean bean) {
}
},0,0);
}
/**

View File

@@ -0,0 +1,127 @@
package com.yunbao.faceunity.data;
import com.faceunity.core.entity.FUBundleData;
import com.faceunity.core.enumeration.FUAITypeEnum;
import com.faceunity.core.faceunity.FUAIKit;
import com.faceunity.core.faceunity.FURenderKit;
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
import com.yunbao.faceunity.entity.LightMakeupBean;
import com.yunbao.faceunity.infe.AbstractLightMakeupDataFactory;
import com.yunbao.faceunity.repo.FaceBeautySource;
import com.yunbao.faceunity.repo.LightMakeupSource;
import com.yunbao.faceunity.utils.FaceUnityConfig;
import java.util.ArrayList;
/**
* DESC轻美妆业务工厂
* Created on 2021/3/3
*/
public class LightMakeupDataFactory extends AbstractLightMakeupDataFactory {
/*渲染控制器*/
private FURenderKit mFURenderKit = FURenderKit.getInstance();
/* 轻美妆队列 */
private ArrayList<LightMakeupBean> lightMakeupBeans;
/* 当前轻美妆选中下标 */
private int currentLightMakeupIndex;
public LightMakeupDataFactory(int index) {
currentLightMakeupIndex = index;
lightMakeupBeans = LightMakeupSource.buildLightMakeup();
}
/**
* 获取轻美妆队列
*
* @return
*/
@Override
public ArrayList<LightMakeupBean> getLightMakeUpBeans() {
return lightMakeupBeans;
}
/**
* 获取轻美妆下标
*
* @return
*/
@Override
public int getCurrentLightMakeupIndex() {
return currentLightMakeupIndex;
}
/**
* 设置轻美妆下标
*
* @param currentLightMakeupIndex
*/
@Override
public void setCurrentLightMakeupIndex(int currentLightMakeupIndex) {
this.currentLightMakeupIndex = currentLightMakeupIndex;
}
/**
* 切换轻美妆
*
* @param data
*/
@Override
public void onLightMakeupSelected(LightMakeupBean data) {
if (data.getKey() == null) {
mFURenderKit.setLightMakeup(null);
} else {
Runnable runnable = LightMakeupSource.LightMakeupParams.get(data.getKey());
if (runnable != null) {
runnable.run();
}
onLightMakeupIntensityChanged(data.getIntensity());
}
if (mFURenderKit.getFaceBeauty() != null) {
mFURenderKit.getFaceBeauty().setFilterName(data.getFilterName());
mFURenderKit.getFaceBeauty().setFilterIntensity(data.getFilterIntensity());
}
}
/**
* 修改强度
*
* @param intensity
*/
@Override
public void onLightMakeupIntensityChanged(double intensity) {
if (mFURenderKit.getLightMakeup() != null) {
mFURenderKit.getLightMakeup().setMakeupIntensity(intensity);
}
if (mFURenderKit.getFaceBeauty() != null) {
mFURenderKit.getFaceBeauty().setFilterIntensity(intensity);
}
}
/**
* FURenderKit加载当前特效
*/
public void bindCurrentRenderer() {
mFURenderKit.setFaceBeauty(FaceBeautySource.clone(FaceBeautyDataFactory.faceBeauty));
FUAIKit.getInstance().setMaxFaces(4);
LightMakeupBean lightMakeupBean = lightMakeupBeans.get(currentLightMakeupIndex);
onLightMakeupSelected(lightMakeupBean);
if (FaceUnityConfig.IS_OPEN_LAND_MARK) {
ExpressionRecognition expressionRecognition = new ExpressionRecognition(new FUBundleData(FaceUnityConfig.BUNDLE_LANDMARKS));
expressionRecognition.setLandmarksType(FUAITypeEnum.FUAITYPE_FACELANDMARKS239);
mFURenderKit.getPropContainer().addProp(expressionRecognition);
}
}
}

View File

@@ -1,38 +1,59 @@
package com.yunbao.faceunity.data;
import androidx.annotation.NonNull;
import com.faceunity.core.entity.FUBundleData;
import com.faceunity.core.enumeration.FUAITypeEnum;
import com.faceunity.core.faceunity.FUAIKit;
import com.faceunity.core.faceunity.FURenderKit;
import com.faceunity.core.model.prop.Prop;
import com.faceunity.core.model.prop.arMask.ARMask;
import com.faceunity.core.model.prop.bigHead.BigHead;
import com.faceunity.core.model.prop.expression.ExpressionRecognition;
import com.faceunity.core.model.prop.faceWarp.FaceWarp;
import com.faceunity.core.model.prop.gesture.GestureRecognition;
import com.faceunity.core.model.prop.sticker.Sticker;
import com.yunbao.faceunity.entity.FunctionEnum;
import com.yunbao.faceunity.entity.PropBean;
import com.yunbao.faceunity.infe.AbstractPropDataFactory;
import com.yunbao.faceunity.repo.PropSource;
import com.yunbao.faceunity.utils.FaceUnityConfig;
import java.util.ArrayList;
/**
* DESC道具业务工厂
* DESC道具业务工厂道具贴图、AR面具、搞笑大头、表情识别、哈哈镜、手势识别
* Created on 2021/3/2
*/
public class PropDataFactory extends AbstractPropDataFactory {
public interface PropListener {
void onItemSelected(PropBean bean);
}
/*渲染控制器*/
private final FURenderKit mFURenderKit = FURenderKit.getInstance();
/*道具列表*/
private final ArrayList<PropBean> propBeans;
/*默认选中下标*/
private int currentPropIndex;
/*当前道具*/
public Prop currentProp;
/*回调接口*/
private final PropListener mPropListener;
/*道具类型*/
private final int propType;
public PropDataFactory(int index) {
public PropDataFactory(PropListener listener, int type, int index) {
mPropListener = listener;
propType = type;
currentPropIndex = index;
propBeans = PropSource.buildPropBeans();
propBeans = PropSource.buildPropBeans(type);
}
@@ -67,20 +88,47 @@ public class PropDataFactory extends AbstractPropDataFactory {
return propBeans;
}
@Override
public void onItemSelected(PropBean bean) {
onPropSelected(bean);
mPropListener.onItemSelected(bean);
}
/**
* 道具选中
* 其他道具
*
* @param bean
*/
@Override
public void onItemSelected(PropBean bean) {
private void onPropSelected(PropBean bean) {
String path = bean.getPath();
if (path == null || path.trim().length() == 0) {
mFURenderKit.getPropContainer().removeAllProp();
currentProp = null;
return;
}
Prop prop = new Sticker(new FUBundleData(path));
Prop prop = null;
switch (propType) {
case FunctionEnum.STICKER:
prop = new Sticker(new FUBundleData(path));
break;
case FunctionEnum.AR_MASK:
prop = new ARMask(new FUBundleData(path));
break;
case FunctionEnum.BIG_HEAD:
prop = new BigHead(new FUBundleData(path));
break;
case FunctionEnum.EXPRESSION_RECOGNITION:
prop = new ExpressionRecognition(new FUBundleData(path));
break;
case FunctionEnum.FACE_WARP:
prop = new FaceWarp(new FUBundleData(path));
break;
case FunctionEnum.GESTURE_RECOGNITION:
prop = new GestureRecognition(new FUBundleData(path));
break;
}
mFURenderKit.getPropContainer().replaceProp(currentProp, prop);
currentProp = prop;
}
@@ -90,7 +138,25 @@ public class PropDataFactory extends AbstractPropDataFactory {
* FURenderKit加载当前特效
*/
public void bindCurrentRenderer() {
if (propType == FunctionEnum.GESTURE_RECOGNITION) {
FUAIKit.getInstance().loadAIProcessor(FaceUnityConfig.BUNDLE_AI_HAND, FUAITypeEnum.FUAITYPE_HANDGESTURE);
}
if (propType == FunctionEnum.BIG_HEAD) {
FUAIKit.getInstance().setMaxFaces(1);
} else {
FUAIKit.getInstance().setMaxFaces(4);
}
mFURenderKit.setFaceBeauty(FaceBeautyDataFactory.faceBeauty);
PropBean propBean = propBeans.get(currentPropIndex);
onItemSelected(propBean);
}
/**
* 结束需要释放AI驱动
*/
public void releaseAIProcessor() {
if (propType == FunctionEnum.GESTURE_RECOGNITION) {
FUAIKit.getInstance().releaseAIProcessor(FUAITypeEnum.FUAITYPE_HANDGESTURE);
}
}
}