From c634d29e7918e49e325efea79ee2ec13bde1d9a6 Mon Sep 17 00:00:00 2001 From: zlzw <583819556@qq.com> Date: Mon, 19 Sep 2022 15:43:06 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A1=A5=E5=85=85=E7=BE=8E=E9=A2=9C=E6=A8=A1?= =?UTF-8?q?=E5=9E=8B=E5=92=8C=E7=BE=8E=E9=A2=9C=E9=85=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- FaceUnity/build.gradle | 3 + .../com/yunbao/faceunity/FaceManager.java | 2 + .../faceunity/control/AnimojiControlView.kt | 149 ++++ .../control/BodyBeautyControlView.java | 242 ----- .../control/BodyBeautyControlView.kt | 205 +++++ .../control/FaceBeautyControlView.java | 463 ---------- .../control/FaceBeautyControlView.kt | 826 ++++++++++++++++++ .../faceunity/control/MakeupControlView.java | 2 +- .../faceunity/control/PropControlView.java | 2 +- .../faceunity/data/AnimojiDataFactory.java | 166 ++++ .../faceunity/data/AvatarDataFactory.java | 158 ++++ .../faceunity/data/BgSegGreenDataFactory.java | 347 ++++++++ .../yunbao/faceunity/data/FaceBeautyData.java | 101 +++ .../faceunity/data/FaceBeautyDataFactory.java | 196 ++++- .../faceunity/data/FaceUnityDataFactory.java | 20 +- .../data/LightMakeupDataFactory.java | 127 +++ .../faceunity/data/PropDataFactory.java | 84 +- .../faceunity/entity/AnimationFilterBean.java | 27 + .../yunbao/faceunity/entity/AnimojiBean.kt | 9 + .../com/yunbao/faceunity/entity/AvatarBean.kt | 10 + .../entity/BgSegGreenBackgroundBean.kt | 11 + .../yunbao/faceunity/entity/BgSegGreenBean.kt | 18 + .../entity/BgSegGreenSafeAreaBean.kt | 32 + .../faceunity/entity/FaceBeautyBean.java | 70 -- .../yunbao/faceunity/entity/FaceBeautyBean.kt | 47 + .../faceunity/entity/FaceBeautyStyleBean.kt | 10 + .../yunbao/faceunity/entity/FunctionEnum.java | 25 + .../faceunity/entity/LightMakeupBean.java | 67 ++ .../faceunity/entity/ModelAttributeData.java | 51 -- .../faceunity/entity/ModelAttributeData.kt | 12 + .../com/yunbao/faceunity/entity/PropBean.java | 32 - .../com/yunbao/faceunity/entity/PropBean.kt | 14 + .../yunbao/faceunity/entity/PropCustomBean.kt | 18 + .../infe/AbstractAnimojiDataFactory.kt | 31 + .../infe/AbstractAvatarDataFactory.kt | 35 + .../infe/AbstractBgSegGreenDataFactory.kt | 97 ++ .../infe/AbstractFaceBeautyDataFactory.java | 103 --- .../infe/AbstractFaceBeautyDataFactory.kt | 105 +++ .../infe/AbstractLightMakeupDataFactory.java | 28 + .../infe/AbstractPropCustomDataFactory.kt | 45 + .../infe/AbstractPropDataFactory.java | 42 - .../faceunity/infe/AbstractPropDataFactory.kt | 33 + .../yunbao/faceunity/repo/AnimojiSource.java | 59 ++ .../yunbao/faceunity/repo/AvatarSource.java | 160 ++++ .../faceunity/repo/BgSegGreenSource.java | 145 +++ .../faceunity/repo/FaceBeautySource.java | 439 +++++++++- .../faceunity/repo/LightMakeupSource.java | 402 +++++++++ .../faceunity/repo/PortraitSegmentSource.java | 107 +++ .../com/yunbao/faceunity/repo/PropSource.java | 75 +- .../yunbao/faceunity/ui/FaceUnityView.java | 70 +- .../ui/fragments/FaceContainerFragment.java | 17 + .../com/yunbao/faceunity/utils/FUUtils.java | 271 ++++++ .../yunbao/faceunity/utils/FaceUnityData.java | 7 + .../com/yunbao/faceunity/utils/FileUtils.java | 580 ++++++++++++ .../yunbao/faceunity/utils/Uri2PathUtil.java | 161 ++++ .../drawable/icon_beauty_style_1_selector.xml | 5 + .../drawable/icon_beauty_style_2_selector.xml | 5 + .../drawable/icon_beauty_style_3_selector.xml | 5 + .../drawable/icon_beauty_style_4_selector.xml | 5 + .../drawable/icon_beauty_style_5_selector.xml | 5 + .../drawable/icon_beauty_style_6_selector.xml | 5 + .../drawable/icon_beauty_style_7_selector.xml | 5 + .../icon_beauty_style_none_selector.xml | 5 + .../drawable/icon_green_color_selector.xml | 5 + .../icon_green_safe_area_close_selector.xml | 5 + .../icon_green_safe_area_open_selector.xml | 5 + .../icon_green_similarityr_close_selector.xml | 5 + .../icon_green_similarityr_open_selector.xml | 5 + .../icon_green_smooth_close_selector.xml | 5 + .../icon_green_smooth_open_selector.xml | 5 + ...icon_green_transparency_close_selector.xml | 5 + .../icon_green_transparency_open_selector.xml | 5 + .../main/res/layout/layout_animo_control.xml | 64 ++ .../res/layout/layout_body_beauty_control.xml | 131 ++- .../res/layout/layout_face_beauty_control.xml | 84 +- .../src/main/res/layout/layout_faceunity.xml | 118 +-- .../res/mipmap-xxhdpi/ico_home_animoji.png | Bin 0 -> 6360 bytes .../res/mipmap-xxhdpi/ico_home_beauty.png | Bin 0 -> 3636 bytes .../mipmap-xxhdpi/ico_home_beauty_body.png | Bin 0 -> 4911 bytes .../res/mipmap-xxhdpi/ico_home_big_head.png | Bin 0 -> 5949 bytes .../mipmap-xxhdpi/ico_home_fine_sticker.png | Bin 0 -> 5639 bytes .../res/mipmap-xxhdpi/ico_home_makeup.png | Bin 0 -> 4862 bytes .../res/mipmap-xxhdpi/ico_home_sticker.png | Bin 0 -> 4821 bytes .../res/mipmap-xxhdpi/icon_animoji_baihu.png | Bin 0 -> 963682 bytes .../res/mipmap-xxhdpi/icon_animoji_baimao.png | Bin 0 -> 31803 bytes .../icon_animoji_cartoon_princess.png | Bin 0 -> 452179 bytes .../mipmap-xxhdpi/icon_animoji_douniuquan.png | Bin 0 -> 29563 bytes .../mipmap-xxhdpi/icon_animoji_frog_st.png | Bin 0 -> 27178 bytes .../mipmap-xxhdpi/icon_animoji_hashiqi.png | Bin 0 -> 36726 bytes .../res/mipmap-xxhdpi/icon_animoji_hetun.png | Bin 0 -> 28557 bytes .../mipmap-xxhdpi/icon_animoji_huangya.png | Bin 0 -> 35434 bytes .../res/mipmap-xxhdpi/icon_animoji_kaola.png | Bin 0 -> 46653 bytes .../mipmap-xxhdpi/icon_animoji_kuloutou.png | Bin 0 -> 25408 bytes .../res/mipmap-xxhdpi/icon_animoji_qgirl.png | Bin 0 -> 79371 bytes .../res/mipmap-xxhdpi/icon_animoji_wuxia.png | Bin 0 -> 422842 bytes .../main/res/mipmap-xxhdpi/icon_ar_baozi.png | Bin 0 -> 19777 bytes .../res/mipmap-xxhdpi/icon_ar_bluebird.png | Bin 0 -> 55764 bytes .../res/mipmap-xxhdpi/icon_ar_fenhudie.png | Bin 0 -> 59260 bytes .../res/mipmap-xxhdpi/icon_ar_lanhudie.png | Bin 0 -> 60726 bytes .../main/res/mipmap-xxhdpi/icon_ar_tiger.png | Bin 0 -> 20662 bytes .../res/mipmap-xxhdpi/icon_ar_tiger_bai.png | Bin 0 -> 56732 bytes .../res/mipmap-xxhdpi/icon_ar_tiger_huang.png | Bin 0 -> 55429 bytes .../res/mipmap-xxhdpi/icon_ar_xiongmao.png | Bin 0 -> 17727 bytes .../res/mipmap-xxhdpi/icon_avatar_female.png | Bin 0 -> 37928 bytes .../res/mipmap-xxhdpi/icon_avatar_male.png | Bin 0 -> 32877 bytes .../icon_beauty_box_style_1_checked.png | Bin 0 -> 6641 bytes .../icon_beauty_box_style_1_normal.png | Bin 0 -> 4940 bytes .../icon_beauty_box_style_2_checked.png | Bin 0 -> 7481 bytes .../icon_beauty_box_style_2_normal.png | Bin 0 -> 5479 bytes .../icon_beauty_box_style_3_checked.png | Bin 0 -> 7607 bytes .../icon_beauty_box_style_3_normal.png | Bin 0 -> 5530 bytes .../icon_beauty_box_style_4_checked.png | Bin 0 -> 7074 bytes .../icon_beauty_box_style_4_normal.png | Bin 0 -> 5255 bytes .../icon_beauty_box_style_5_checked.png | Bin 0 -> 7852 bytes .../icon_beauty_box_style_5_normal.png | Bin 0 -> 5673 bytes .../icon_beauty_box_style_6_checked.png | Bin 0 -> 8126 bytes .../icon_beauty_box_style_6_normal.png | Bin 0 -> 5824 bytes .../icon_beauty_box_style_7_checked.png | Bin 0 -> 10085 bytes .../icon_beauty_box_style_7_normal.png | Bin 0 -> 6989 bytes .../icon_beauty_box_style_none_checked.png | Bin 0 -> 6773 bytes .../icon_beauty_box_style_none_normal.png | Bin 0 -> 5143 bytes .../icon_beauty_filter_bailiang_2.png | Bin 0 -> 55430 bytes .../icon_beauty_filter_bailiang_3.png | Bin 0 -> 54807 bytes .../icon_beauty_filter_bailiang_4.png | Bin 0 -> 51970 bytes .../icon_beauty_filter_bailiang_5.png | Bin 0 -> 54761 bytes .../icon_beauty_filter_bailiang_6.png | Bin 0 -> 54088 bytes .../icon_beauty_filter_bailiang_7.png | Bin 0 -> 54199 bytes .../icon_beauty_filter_fennen_2.png | Bin 0 -> 43995 bytes .../icon_beauty_filter_fennen_3.png | Bin 0 -> 45500 bytes .../icon_beauty_filter_fennen_5.png | Bin 0 -> 44792 bytes .../icon_beauty_filter_fennen_6.png | Bin 0 -> 45406 bytes .../icon_beauty_filter_fennen_7.png | Bin 0 -> 47013 bytes .../icon_beauty_filter_fennen_8.png | Bin 0 -> 43051 bytes .../icon_beauty_filter_gexing_1.png | Bin 0 -> 53747 bytes .../icon_beauty_filter_gexing_10.png | Bin 0 -> 49285 bytes .../icon_beauty_filter_gexing_11.png | Bin 0 -> 51553 bytes .../icon_beauty_filter_gexing_2.png | Bin 0 -> 48799 bytes .../icon_beauty_filter_gexing_3.png | Bin 0 -> 50703 bytes .../icon_beauty_filter_gexing_4.png | Bin 0 -> 48465 bytes .../icon_beauty_filter_gexing_5.png | Bin 0 -> 47163 bytes .../icon_beauty_filter_gexing_7.png | Bin 0 -> 50507 bytes .../icon_beauty_filter_heibai_1.png | Bin 0 -> 26034 bytes .../icon_beauty_filter_heibai_2.png | Bin 0 -> 25303 bytes .../icon_beauty_filter_heibai_3.png | Bin 0 -> 44568 bytes .../icon_beauty_filter_heibai_4.png | Bin 0 -> 48682 bytes .../icon_beauty_filter_lengsediao_11.png | Bin 0 -> 42372 bytes .../icon_beauty_filter_lengsediao_2.png | Bin 0 -> 41424 bytes .../icon_beauty_filter_lengsediao_3.png | Bin 0 -> 44595 bytes .../icon_beauty_filter_lengsediao_4.png | Bin 0 -> 42914 bytes .../icon_beauty_filter_lengsediao_7.png | Bin 0 -> 40645 bytes .../icon_beauty_filter_lengsediao_8.png | Bin 0 -> 44089 bytes .../icon_beauty_filter_natural_2.png | Bin 0 -> 63817 bytes .../icon_beauty_filter_natural_3.png | Bin 0 -> 64354 bytes .../icon_beauty_filter_natural_4.png | Bin 0 -> 65297 bytes .../icon_beauty_filter_natural_5.png | Bin 0 -> 64627 bytes .../icon_beauty_filter_natural_6.png | Bin 0 -> 64222 bytes .../icon_beauty_filter_natural_7.png | Bin 0 -> 65091 bytes .../icon_beauty_filter_natural_8.png | Bin 0 -> 64898 bytes .../icon_beauty_filter_nuansediao_1.png | Bin 0 -> 55782 bytes .../icon_beauty_filter_nuansediao_2.png | Bin 0 -> 59594 bytes .../icon_beauty_filter_peach_1.png | Bin 0 -> 46420 bytes .../icon_beauty_filter_peach_2.png | Bin 0 -> 37645 bytes .../icon_beauty_filter_peach_3.png | Bin 0 -> 45448 bytes .../icon_beauty_filter_peach_4.png | Bin 0 -> 45333 bytes .../icon_beauty_filter_peach_5.png | Bin 0 -> 46660 bytes .../icon_beauty_filter_peach_6.png | Bin 0 -> 42852 bytes .../icon_beauty_filter_peach_7.png | Bin 0 -> 43597 bytes .../icon_beauty_filter_peach_8.png | Bin 0 -> 42136 bytes .../icon_beauty_filter_texture_gray_2.png | Bin 0 -> 56773 bytes .../icon_beauty_filter_texture_gray_3.png | Bin 0 -> 56883 bytes .../icon_beauty_filter_texture_gray_4.png | Bin 0 -> 53876 bytes .../icon_beauty_filter_texture_gray_5.png | Bin 0 -> 56066 bytes .../icon_beauty_filter_texture_gray_6.png | Bin 0 -> 55849 bytes .../icon_beauty_filter_texture_gray_7.png | Bin 0 -> 54239 bytes .../icon_beauty_filter_texture_gray_8.png | Bin 0 -> 58393 bytes .../icon_beauty_filter_xiaoqingxin_1.png | Bin 0 -> 55846 bytes .../icon_beauty_filter_xiaoqingxin_3.png | Bin 0 -> 58545 bytes .../icon_beauty_filter_xiaoqingxin_4.png | Bin 0 -> 58584 bytes .../icon_beauty_filter_xiaoqingxin_6.png | Bin 0 -> 59612 bytes .../main/res/mipmap-xxhdpi/icon_big_head.png | Bin 0 -> 27546 bytes .../res/mipmap-xxhdpi/icon_big_head_blush.png | Bin 0 -> 29389 bytes .../icon_big_head_dark_circles.png | Bin 0 -> 28985 bytes .../icon_big_head_husky_face.png | Bin 0 -> 38009 bytes .../icon_big_head_sausage_mouth.png | Bin 0 -> 31318 bytes .../icon_big_head_smiling_head.png | Bin 0 -> 28798 bytes .../res/mipmap-xxhdpi/icon_cartoon_anime.png | Bin 0 -> 56004 bytes .../mipmap-xxhdpi/icon_cartoon_graffiti.png | Bin 0 -> 58209 bytes .../icon_cartoon_oilpainting.png | Bin 0 -> 63362 bytes .../icon_cartoon_pencilpainting.png | Bin 0 -> 42662 bytes .../icon_cartoon_penpainting.png | Bin 0 -> 37375 bytes .../icon_cartoon_portrait_dynamiceffect.png | Bin 0 -> 51741 bytes .../icon_cartoon_sandlpainting.png | Bin 0 -> 60853 bytes .../res/mipmap-xxhdpi/icon_cartoon_sketch.png | Bin 0 -> 31726 bytes .../res/mipmap-xxhdpi/icon_control_add.png | Bin 0 -> 1855 bytes .../res/mipmap-xxhdpi/icon_control_return.png | Bin 0 -> 3814 bytes .../mipmap-xxhdpi/icon_control_square_add.png | Bin 0 -> 1755 bytes .../icon_expression_future_warrior.png | Bin 0 -> 60766 bytes .../icon_expression_jet_mask.png | Bin 0 -> 16497 bytes .../icon_expression_luhantongkuan_ztt_fu.png | Bin 0 -> 57400 bytes .../icon_expression_qingqing_ztt_fu.png | Bin 0 -> 58358 bytes .../mipmap-xxhdpi/icon_expression_sdx2.png | Bin 0 -> 39067 bytes .../icon_expression_xiaobianzi_zh_fu.png | Bin 0 -> 35900 bytes .../icon_expression_xiaoxueshen_ztt_fu.png | Bin 0 -> 50070 bytes .../res/mipmap-xxhdpi/icon_face_warp_2.png | Bin 0 -> 30526 bytes .../res/mipmap-xxhdpi/icon_face_warp_3.png | Bin 0 -> 25375 bytes .../res/mipmap-xxhdpi/icon_face_warp_4.png | Bin 0 -> 29085 bytes .../res/mipmap-xxhdpi/icon_face_warp_5.png | Bin 0 -> 30221 bytes .../res/mipmap-xxhdpi/icon_face_warp_6.png | Bin 0 -> 28391 bytes .../res/mipmap-xxhdpi/icon_gesture_cute.png | Bin 0 -> 56871 bytes .../res/mipmap-xxhdpi/icon_gesture_flower.png | Bin 0 -> 22079 bytes .../mipmap-xxhdpi/icon_gesture_koreaheart.png | Bin 0 -> 53380 bytes .../res/mipmap-xxhdpi/icon_gesture_rain.png | Bin 0 -> 30823 bytes .../res/mipmap-xxhdpi/icon_gesture_six.png | Bin 0 -> 42269 bytes .../res/mipmap-xxhdpi/icon_gesture_snow.png | Bin 0 -> 24496 bytes .../res/mipmap-xxhdpi/icon_green_bg_beach.png | Bin 0 -> 50445 bytes .../mipmap-xxhdpi/icon_green_bg_classroom.png | Bin 0 -> 37664 bytes .../mipmap-xxhdpi/icon_green_bg_forest.png | Bin 0 -> 53948 bytes .../icon_green_color_checked.png | Bin 0 -> 12135 bytes .../mipmap-xxhdpi/icon_green_color_normal.png | Bin 0 -> 8068 bytes .../mipmap-xxhdpi/icon_green_ink_painting.png | Bin 0 -> 59586 bytes .../mipmap-xxhdpi/icon_green_safe_area1.png | Bin 0 -> 3601 bytes .../mipmap-xxhdpi/icon_green_safe_area2.png | Bin 0 -> 3648 bytes .../icon_green_safe_area_close_normal.png | Bin 0 -> 3750 bytes .../icon_green_safe_area_open_normal.png | Bin 0 -> 3985 bytes .../res/mipmap-xxhdpi/icon_green_science.png | Bin 0 -> 53154 bytes .../icon_green_similarityr_close_checked.png | Bin 0 -> 9954 bytes .../icon_green_similarityr_close_normal.png | Bin 0 -> 6862 bytes .../icon_green_similarityr_open_checked.png | Bin 0 -> 10228 bytes .../icon_green_similarityr_open_normal.png | Bin 0 -> 7114 bytes .../icon_green_smooth_close_checked.png | Bin 0 -> 8411 bytes .../icon_green_smooth_close_normal.png | Bin 0 -> 5881 bytes .../icon_green_smooth_open_checked.png | Bin 0 -> 8677 bytes .../icon_green_smooth_open_normal.png | Bin 0 -> 6099 bytes .../icon_green_transparency_close_checked.png | Bin 0 -> 6223 bytes .../icon_green_transparency_close_normal.png | Bin 0 -> 4618 bytes .../icon_green_transparency_open_checked.png | Bin 0 -> 6560 bytes .../icon_green_transparency_open_normal.png | Bin 0 -> 4929 bytes .../icon_light_makeup_blush_01.png | Bin 0 -> 36383 bytes .../icon_light_makeup_blush_02.png | Bin 0 -> 38232 bytes .../icon_light_makeup_blush_03.png | Bin 0 -> 38850 bytes .../icon_light_makeup_blush_04.png | Bin 0 -> 37773 bytes .../icon_light_makeup_blush_05.png | Bin 0 -> 37141 bytes .../icon_light_makeup_blush_06.png | Bin 0 -> 37394 bytes .../icon_light_makeup_blush_07.png | Bin 0 -> 38285 bytes .../icon_light_makeup_blush_08.png | Bin 0 -> 37991 bytes .../icon_light_makeup_blush_09.png | Bin 0 -> 37452 bytes .../icon_light_makeup_blush_10.png | Bin 0 -> 37424 bytes .../icon_light_makeup_blush_11.png | Bin 0 -> 37947 bytes .../icon_light_makeup_blush_12.png | Bin 0 -> 36155 bytes .../icon_light_makeup_blush_13.png | Bin 0 -> 38012 bytes .../icon_light_makeup_blush_14.png | Bin 0 -> 36417 bytes .../icon_light_makeup_blush_15.png | Bin 0 -> 37760 bytes .../icon_light_makeup_blush_16.png | Bin 0 -> 36828 bytes .../icon_light_makeup_blush_17.png | Bin 0 -> 36169 bytes .../icon_light_makeup_blush_18.png | Bin 0 -> 36770 bytes .../icon_light_makeup_blush_19.png | Bin 0 -> 36440 bytes .../icon_light_makeup_blush_20.png | Bin 0 -> 37130 bytes .../icon_light_makeup_blush_21.png | Bin 0 -> 37110 bytes .../icon_light_makeup_blush_22.png | Bin 0 -> 36371 bytes .../icon_light_makeup_blush_23.png | Bin 0 -> 36503 bytes .../icon_light_makeup_blush_24.png | Bin 0 -> 36582 bytes .../icon_light_makeup_boyfriend.png | Bin 0 -> 52799 bytes .../mipmap-xxhdpi/icon_light_makeup_clear.png | Bin 0 -> 61236 bytes .../icon_light_makeup_eyebrow_01.png | Bin 0 -> 5887 bytes .../icon_light_makeup_eyebrow_02.png | Bin 0 -> 7261 bytes .../icon_light_makeup_eyebrow_03.png | Bin 0 -> 5977 bytes .../icon_light_makeup_eyebrow_04.png | Bin 0 -> 5355 bytes .../icon_light_makeup_eyebrow_05.png | Bin 0 -> 5664 bytes .../icon_light_makeup_eyebrow_06.png | Bin 0 -> 5464 bytes .../icon_light_makeup_eyebrow_07.png | Bin 0 -> 4751 bytes .../icon_light_makeup_eyebrow_08.png | Bin 0 -> 5041 bytes .../icon_light_makeup_eyebrow_09.png | Bin 0 -> 5303 bytes .../icon_light_makeup_eyebrow_10.png | Bin 0 -> 6489 bytes .../icon_light_makeup_eyebrow_11.png | Bin 0 -> 6537 bytes .../icon_light_makeup_eyebrow_12.png | Bin 0 -> 5881 bytes .../icon_light_makeup_eyebrow_13.png | Bin 0 -> 5693 bytes .../icon_light_makeup_eyebrow_14.png | Bin 0 -> 5331 bytes .../icon_light_makeup_eyebrow_15.png | Bin 0 -> 4678 bytes .../icon_light_makeup_eyebrow_16.png | Bin 0 -> 6373 bytes .../icon_light_makeup_eyebrow_17.png | Bin 0 -> 5829 bytes .../icon_light_makeup_eyebrow_18.png | Bin 0 -> 5038 bytes .../icon_light_makeup_eyebrow_19.png | Bin 0 -> 6627 bytes .../icon_light_makeup_eyelash_01.png | Bin 0 -> 11065 bytes .../icon_light_makeup_eyelash_02.png | Bin 0 -> 10274 bytes .../icon_light_makeup_eyelash_03.png | Bin 0 -> 14340 bytes .../icon_light_makeup_eyelash_04.png | Bin 0 -> 10382 bytes .../icon_light_makeup_eyelash_05.png | Bin 0 -> 10521 bytes .../icon_light_makeup_eyelash_06.png | Bin 0 -> 12015 bytes .../icon_light_makeup_eyelash_07.png | Bin 0 -> 10646 bytes .../icon_light_makeup_eyelash_08.png | Bin 0 -> 11019 bytes .../icon_light_makeup_eyeliner_01.png | Bin 0 -> 7968 bytes .../icon_light_makeup_eyeliner_02.png | Bin 0 -> 7720 bytes .../icon_light_makeup_eyeliner_03.png | Bin 0 -> 8378 bytes .../icon_light_makeup_eyeliner_04.png | Bin 0 -> 8102 bytes .../icon_light_makeup_eyeliner_05.png | Bin 0 -> 8074 bytes .../icon_light_makeup_eyeliner_06.png | Bin 0 -> 7485 bytes .../icon_light_makeup_eyeliner_07.png | Bin 0 -> 7514 bytes .../icon_light_makeup_eyeliner_08.png | Bin 0 -> 7893 bytes .../icon_light_makeup_eyepupil_01.png | Bin 0 -> 18121 bytes .../icon_light_makeup_eyepupil_02.png | Bin 0 -> 16915 bytes .../icon_light_makeup_eyepupil_03.png | Bin 0 -> 17836 bytes .../icon_light_makeup_eyepupil_04.png | Bin 0 -> 13128 bytes .../icon_light_makeup_eyepupil_05.png | Bin 0 -> 16824 bytes .../icon_light_makeup_eyepupil_06.png | Bin 0 -> 18115 bytes .../icon_light_makeup_eyepupil_07.png | Bin 0 -> 15894 bytes .../icon_light_makeup_eyepupil_08.png | Bin 0 -> 16161 bytes .../icon_light_makeup_eyepupil_09.png | Bin 0 -> 16157 bytes .../icon_light_makeup_eyeshadow_01.png | Bin 0 -> 20905 bytes .../icon_light_makeup_eyeshadow_02.png | Bin 0 -> 11637 bytes .../icon_light_makeup_eyeshadow_03.png | Bin 0 -> 17963 bytes .../icon_light_makeup_eyeshadow_04.png | Bin 0 -> 12538 bytes .../icon_light_makeup_eyeshadow_05.png | Bin 0 -> 13849 bytes .../icon_light_makeup_eyeshadow_06.png | Bin 0 -> 13708 bytes .../icon_light_makeup_eyeshadow_07.png | Bin 0 -> 15295 bytes .../icon_light_makeup_eyeshadow_08.png | Bin 0 -> 13459 bytes .../icon_light_makeup_eyeshadow_09.png | Bin 0 -> 11928 bytes .../icon_light_makeup_eyeshadow_10.png | Bin 0 -> 21173 bytes .../icon_light_makeup_eyeshadow_11.png | Bin 0 -> 15331 bytes .../icon_light_makeup_eyeshadow_12.png | Bin 0 -> 19566 bytes .../icon_light_makeup_eyeshadow_13.png | Bin 0 -> 20722 bytes .../icon_light_makeup_eyeshadow_14.png | Bin 0 -> 17591 bytes .../icon_light_makeup_eyeshadow_15.png | Bin 0 -> 14034 bytes .../icon_light_makeup_eyeshadow_16.png | Bin 0 -> 21367 bytes .../icon_light_makeup_eyeshadow_17.png | Bin 0 -> 19905 bytes .../icon_light_makeup_eyeshadow_18.png | Bin 0 -> 21613 bytes .../icon_light_makeup_eyeshadow_19.png | Bin 0 -> 20411 bytes .../icon_light_makeup_eyeshadow_20.png | Bin 0 -> 16327 bytes .../icon_light_makeup_eyeshadow_21.png | Bin 0 -> 21807 bytes .../icon_light_makeup_eyeshadow_22.png | Bin 0 -> 19770 bytes .../icon_light_makeup_grapefruit.png | Bin 0 -> 58730 bytes .../icon_light_makeup_lip_01.png | Bin 0 -> 8783 bytes .../icon_light_makeup_lip_02.png | Bin 0 -> 9037 bytes .../icon_light_makeup_lip_03.png | Bin 0 -> 8602 bytes .../icon_light_makeup_lip_10.png | Bin 0 -> 8709 bytes .../icon_light_makeup_lip_12.png | Bin 0 -> 8834 bytes .../icon_light_makeup_lip_13.png | Bin 0 -> 8424 bytes .../icon_light_makeup_lip_14.png | Bin 0 -> 8715 bytes .../icon_light_makeup_lip_15.png | Bin 0 -> 6789 bytes .../icon_light_makeup_lip_16.png | Bin 0 -> 8992 bytes .../icon_light_makeup_lip_17.png | Bin 0 -> 9063 bytes .../icon_light_makeup_lip_18.png | Bin 0 -> 8515 bytes .../icon_light_makeup_lip_19.png | Bin 0 -> 8652 bytes .../icon_light_makeup_lip_20.png | Bin 0 -> 8664 bytes .../icon_light_makeup_lip_21.png | Bin 0 -> 8813 bytes .../icon_light_makeup_lip_22.png | Bin 0 -> 8910 bytes .../icon_light_makeup_peachblossom.png | Bin 0 -> 38882 bytes .../icon_segment_boyfriend_1.png | Bin 0 -> 34993 bytes .../icon_segment_boyfriend_2.png | Bin 0 -> 38992 bytes .../icon_segment_boyfriend_3.png | Bin 0 -> 48230 bytes .../icon_segment_gufeng_zh_fu.png | Bin 0 -> 42095 bytes .../mipmap-xxhdpi/icon_segment_hez_ztt_fu.png | Bin 0 -> 61830 bytes .../icon_segment_human_outline.png | Bin 0 -> 44951 bytes .../mipmap-xxhdpi/icon_segment_ice_lm_fu.png | Bin 0 -> 40686 bytes .../mipmap-xxhdpi/icon_segment_sea_lm_fu.png | Bin 0 -> 28983 bytes .../icon_segment_xiandai_ztt_fu.png | Bin 0 -> 47188 bytes .../mipmap-xxhdpi/icon_sticker_cat_sparks.png | Bin 0 -> 35982 bytes .../mipmap-xxhdpi/icon_sticker_daisypig.png | Bin 0 -> 41881 bytes .../icon_sticker_fu_zh_fenshu.png | Bin 0 -> 43799 bytes .../res/mipmap-xxhdpi/icon_sticker_newy1.png | Bin 0 -> 41305 bytes .../mipmap-xxhdpi/icon_sticker_redribbt.png | Bin 0 -> 48207 bytes .../res/mipmap-xxhdpi/icon_sticker_sdlr.png | Bin 0 -> 56292 bytes .../icon_sticker_xlong_zh_fu.png | Bin 0 -> 15153 bytes .../src/main/res/values-zh-rCN/strings.xml | 3 + FaceUnity/src/main/res/values/strings.xml | 3 + .../yunbao/live/views/LiveRoomViewHolder.java | 1 - 365 files changed, 5751 insertions(+), 1296 deletions(-) create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/control/AnimojiControlView.kt delete mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.kt delete mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/data/AnimojiDataFactory.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/data/AvatarDataFactory.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/data/BgSegGreenDataFactory.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyData.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/data/LightMakeupDataFactory.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimationFilterBean.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimojiBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/AvatarBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBackgroundBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenSafeAreaBean.kt delete mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyStyleBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/FunctionEnum.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/LightMakeupBean.java delete mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.kt delete mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropCustomBean.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAnimojiDataFactory.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAvatarDataFactory.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractBgSegGreenDataFactory.kt delete mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractLightMakeupDataFactory.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropCustomDataFactory.kt delete mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.kt create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/repo/AnimojiSource.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/repo/AvatarSource.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/repo/BgSegGreenSource.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/repo/LightMakeupSource.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/repo/PortraitSegmentSource.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/ui/fragments/FaceContainerFragment.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/utils/FUUtils.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/utils/FaceUnityData.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/utils/FileUtils.java create mode 100644 FaceUnity/src/main/java/com/yunbao/faceunity/utils/Uri2PathUtil.java create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_1_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_2_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_3_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_4_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_5_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_6_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_7_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_beauty_style_none_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_color_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_safe_area_close_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_safe_area_open_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_similarityr_close_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_similarityr_open_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_smooth_close_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_smooth_open_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_transparency_close_selector.xml create mode 100644 FaceUnity/src/main/res/drawable/icon_green_transparency_open_selector.xml create mode 100644 FaceUnity/src/main/res/layout/layout_animo_control.xml create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/ico_home_animoji.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/ico_home_beauty.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/ico_home_beauty_body.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/ico_home_big_head.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/ico_home_fine_sticker.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/ico_home_makeup.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/ico_home_sticker.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_baihu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_baimao.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_cartoon_princess.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_douniuquan.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_frog_st.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_hashiqi.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_hetun.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_huangya.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_kaola.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_kuloutou.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_qgirl.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_animoji_wuxia.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_baozi.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_bluebird.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_fenhudie.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_lanhudie.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_tiger.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_tiger_bai.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_tiger_huang.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_ar_xiongmao.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_avatar_female.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_avatar_male.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_1_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_1_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_2_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_2_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_3_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_3_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_4_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_4_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_5_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_5_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_6_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_6_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_7_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_7_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_none_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_box_style_none_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_bailiang_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_bailiang_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_bailiang_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_bailiang_5.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_bailiang_6.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_bailiang_7.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_fennen_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_fennen_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_fennen_5.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_fennen_6.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_fennen_7.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_fennen_8.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_10.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_11.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_5.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_gexing_7.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_heibai_1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_heibai_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_heibai_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_heibai_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_lengsediao_11.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_lengsediao_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_lengsediao_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_lengsediao_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_lengsediao_7.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_lengsediao_8.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_natural_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_natural_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_natural_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_natural_5.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_natural_6.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_natural_7.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_natural_8.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_nuansediao_1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_nuansediao_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_5.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_6.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_7.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_peach_8.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_texture_gray_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_texture_gray_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_texture_gray_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_texture_gray_5.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_texture_gray_6.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_texture_gray_7.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_texture_gray_8.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_xiaoqingxin_1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_xiaoqingxin_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_xiaoqingxin_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_beauty_filter_xiaoqingxin_6.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_big_head.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_big_head_blush.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_big_head_dark_circles.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_big_head_husky_face.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_big_head_sausage_mouth.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_big_head_smiling_head.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_anime.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_graffiti.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_oilpainting.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_pencilpainting.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_penpainting.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_portrait_dynamiceffect.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_sandlpainting.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_cartoon_sketch.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_control_add.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_control_return.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_control_square_add.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_expression_future_warrior.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_expression_jet_mask.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_expression_luhantongkuan_ztt_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_expression_qingqing_ztt_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_expression_sdx2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_expression_xiaobianzi_zh_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_expression_xiaoxueshen_ztt_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_face_warp_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_face_warp_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_face_warp_4.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_face_warp_5.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_face_warp_6.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_gesture_cute.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_gesture_flower.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_gesture_koreaheart.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_gesture_rain.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_gesture_six.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_gesture_snow.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_bg_beach.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_bg_classroom.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_bg_forest.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_color_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_color_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_ink_painting.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_safe_area1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_safe_area2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_safe_area_close_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_safe_area_open_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_science.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_similarityr_close_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_similarityr_close_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_similarityr_open_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_similarityr_open_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_smooth_close_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_smooth_close_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_smooth_open_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_smooth_open_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_transparency_close_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_transparency_close_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_transparency_open_checked.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_green_transparency_open_normal.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_01.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_02.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_03.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_04.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_05.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_06.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_07.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_08.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_09.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_10.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_11.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_12.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_13.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_14.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_15.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_16.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_17.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_18.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_19.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_20.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_21.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_22.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_23.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_blush_24.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_boyfriend.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_clear.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_01.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_02.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_03.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_04.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_05.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_06.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_07.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_08.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_09.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_10.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_11.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_12.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_13.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_14.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_15.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_16.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_17.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_18.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyebrow_19.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_01.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_02.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_03.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_04.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_05.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_06.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_07.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyelash_08.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_01.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_02.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_03.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_04.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_05.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_06.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_07.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeliner_08.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_01.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_02.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_03.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_04.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_05.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_06.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_07.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_08.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyepupil_09.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_01.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_02.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_03.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_04.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_05.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_06.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_07.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_08.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_09.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_10.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_11.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_12.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_13.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_14.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_15.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_16.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_17.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_18.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_19.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_20.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_21.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_eyeshadow_22.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_grapefruit.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_01.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_02.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_03.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_10.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_12.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_13.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_14.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_15.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_16.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_17.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_18.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_19.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_20.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_21.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_lip_22.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_light_makeup_peachblossom.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_boyfriend_1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_boyfriend_2.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_boyfriend_3.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_gufeng_zh_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_hez_ztt_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_human_outline.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_ice_lm_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_sea_lm_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_segment_xiandai_ztt_fu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_sticker_cat_sparks.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_sticker_daisypig.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_sticker_fu_zh_fenshu.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_sticker_newy1.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_sticker_redribbt.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_sticker_sdlr.png create mode 100644 FaceUnity/src/main/res/mipmap-xxhdpi/icon_sticker_xlong_zh_fu.png diff --git a/FaceUnity/build.gradle b/FaceUnity/build.gradle index f0a600c69..23ed7d11f 100644 --- a/FaceUnity/build.gradle +++ b/FaceUnity/build.gradle @@ -1,5 +1,7 @@ apply plugin: 'com.android.library' apply plugin: 'img-optimizer' +apply plugin: 'kotlin-android' +apply plugin: 'kotlin-android-extensions' android { @@ -59,6 +61,7 @@ dependencies { implementation fileTree(dir: 'libs', include: ['*.jar']) implementation rootProject.ext.dependencies["appcompat-androidx"] implementation rootProject.ext.dependencies["recyclerview-androidx"] + implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" //common implementation project(path: ':common') diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/FaceManager.java b/FaceUnity/src/main/java/com/yunbao/faceunity/FaceManager.java index 83abcb033..d2fca677b 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/FaceManager.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/FaceManager.java @@ -39,6 +39,7 @@ import com.yunbao.faceunity.utils.Authpack; import com.yunbao.faceunity.utils.CSVUtils; import com.yunbao.faceunity.utils.FURenderer; import com.yunbao.faceunity.utils.FaceCameraConfig; +import com.yunbao.faceunity.utils.FaceUnityData; import java.io.File; import java.io.FileOutputStream; @@ -69,6 +70,7 @@ public class FaceManager implements SensorEventListener { if (isInit) { return; } + FaceUnityData.mApplication=context; FURenderManager.setCoreDebug(FULogger.LogLevel.OFF); FURenderManager.setKitDebug(FULogger.LogLevel.OFF); FURenderManager.registerFURender(context, Authpack.A(), new OperateCallback() { diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/control/AnimojiControlView.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/control/AnimojiControlView.kt new file mode 100644 index 000000000..d19d57ab0 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/control/AnimojiControlView.kt @@ -0,0 +1,149 @@ +package com.yunbao.faceunity.control + +import android.animation.ValueAnimator +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import android.view.ViewGroup +import com.yunbao.faceunity.R +import com.yunbao.faceunity.base.BaseDelegate +import com.yunbao.faceunity.base.BaseListAdapter +import com.yunbao.faceunity.base.BaseViewHolder +import com.yunbao.faceunity.entity.AnimationFilterBean +import com.yunbao.faceunity.entity.AnimojiBean +import com.yunbao.faceunity.infe.AbstractAnimojiDataFactory +import kotlinx.android.synthetic.main.layout_animo_control.view.* + + +/** + * + * DESC: + * Created on 2020/12/10 + * + */ +class AnimojiControlView @JvmOverloads constructor(private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + BaseControlView(mContext, attrs, defStyleAttr) { + + + private lateinit var mDataFactory: AbstractAnimojiDataFactory + + private lateinit var mAnimojiAdapter: BaseListAdapter + private lateinit var mAnimationFilterAdapter: BaseListAdapter + + + // region init + init { + LayoutInflater.from(context).inflate(R.layout.layout_animo_control, this) + initView() + initAdapter() + bindListener() + } + + /** + * 给控制绑定AnimojiController,数据工厂 + */ + fun bindDataFactory(dataFactory: AbstractAnimojiDataFactory) { + mDataFactory = dataFactory + mAnimojiAdapter.setData(dataFactory.animojis) + mAnimationFilterAdapter.setData(dataFactory.filters) + } + + /** + * 收回菜单栏 + */ + fun hideControlView() { + rg_anim.check(View.NO_ID) + } + + + private fun initView() { + isBottomShow = true + initHorizontalRecycleView(recycler_view) + } + + private fun initAdapter() { + mAnimojiAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate() { + override fun convert(viewType: Int, helper: BaseViewHolder, data: AnimojiBean, position: Int) { + helper.setImageResource(R.id.iv_control, data.iconId) + helper.itemView.isSelected = position == mDataFactory.currentAnimojiIndex + } + + override fun onItemClickListener(view: View, data: AnimojiBean, position: Int) { + if (mDataFactory.currentAnimojiIndex != position) { + changeAdapterSelected(mAnimojiAdapter, mDataFactory.currentAnimojiIndex, position) + mDataFactory.currentAnimojiIndex = position + mDataFactory.onAnimojiSelected(data) + + } + } + }, R.layout.list_item_control_image_circle) + recycler_view.adapter = mAnimojiAdapter + + mAnimationFilterAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate() { + override fun convert(viewType: Int, helper: BaseViewHolder, data: AnimationFilterBean, position: Int) { + helper.setImageResource(R.id.iv_control, data.iconId) + helper.itemView.isSelected = position == mDataFactory.currentFilterIndex + } + + override fun onItemClickListener(view: View, data: AnimationFilterBean, position: Int) { + if (mDataFactory.currentFilterIndex != position) { + changeAdapterSelected(mAnimationFilterAdapter, mDataFactory.currentFilterIndex, position) + mDataFactory.currentFilterIndex = position + mDataFactory.onFilterSelected(data) + } + } + }, R.layout.list_item_control_image_circle) + } + + private fun bindListener() { + rg_anim.setOnCheckedChangeListener { _, checkedId -> + when (checkedId) { + R.id.cb_animoji -> { + changeBottomLayoutAnimator(true) + recycler_view.adapter = mAnimojiAdapter + } + R.id.cb_filter -> { + changeBottomLayoutAnimator(true) + recycler_view.adapter = mAnimationFilterAdapter + } + else -> { + changeBottomLayoutAnimator(false) + } + } + } + } + // endregion + + + /** + * 底部动画处理 + * @param isOpen Boolean + */ + private fun changeBottomLayoutAnimator(isOpen: Boolean) { + if (isOpen == isBottomShow) { + return + } + + val start = if (isOpen) resources.getDimensionPixelSize(R.dimen.x98) else resources.getDimensionPixelSize(R.dimen.x266) + val end = if (isOpen) resources.getDimensionPixelSize(R.dimen.x266) else resources.getDimensionPixelSize(R.dimen.x98) + + if (bottomLayoutAnimator != null && bottomLayoutAnimator!!.isRunning) { + bottomLayoutAnimator!!.end() + } + bottomLayoutAnimator = ValueAnimator.ofInt(start, end).setDuration(150) + bottomLayoutAnimator!!.addUpdateListener { animation -> + val height = animation.animatedValue as Int + val params = lyt_bottom.layoutParams as ViewGroup.LayoutParams + params.height = height + lyt_bottom.layoutParams = params + if (onBottomAnimatorChangeListener != null) { + val showRate = 1.0f * (height - start) / (end - start) + onBottomAnimatorChangeListener?.onBottomAnimatorChangeListener(if (!isOpen) 1 - showRate else showRate) + } + } + bottomLayoutAnimator!!.start() + isBottomShow = isOpen + } + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.java b/FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.java deleted file mode 100644 index c117e7b46..000000000 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.java +++ /dev/null @@ -1,242 +0,0 @@ -package com.yunbao.faceunity.control; - -import android.content.Context; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; -import androidx.recyclerview.widget.RecyclerView; - -import com.faceunity.core.utils.DecimalUtils; - -import com.yunbao.faceunity.R; -import com.yunbao.faceunity.base.BaseDelegate; -import com.yunbao.faceunity.base.BaseListAdapter; -import com.yunbao.faceunity.base.BaseViewHolder; -import com.yunbao.faceunity.entity.BodyBeautyBean; -import com.yunbao.faceunity.entity.ModelAttributeData; -import com.yunbao.faceunity.infe.AbstractBodyBeautyDataFactory; -import com.yunbao.faceunity.seekbar.DiscreteSeekBar; - -import java.util.ArrayList; -import java.util.HashMap; - -/** - * DESC: - * Created on 2021/4/26 - */ -public class BodyBeautyControlView extends BaseControlView { - - private RecyclerView recyclerView; - private DiscreteSeekBar discreteSeekBar; - private LinearLayout recoverLayout; - private ImageView recoverImageView; - private TextView recoverTextView; - private SwitchCompat switchCompat; - - private AbstractBodyBeautyDataFactory mDataFactory; - private HashMap mModelAttributeRange; - private ArrayList mBodyBeautyBeans; - private BaseListAdapter mBodyAdapter; - private int mBodyIndex = 0; - - - public BodyBeautyControlView(@NonNull Context context) { - super(context); - init(); - } - - public BodyBeautyControlView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - init(); - } - - public BodyBeautyControlView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - private void init() { - LayoutInflater.from(mContext).inflate(R.layout.layout_body_beauty_control, this); - initView(); - initAdapter(); - bindListener(); - } - - - public void bindDataFactory(AbstractBodyBeautyDataFactory dataFactory) { - mDataFactory = dataFactory; - mBodyBeautyBeans = mDataFactory.getBodyBeautyParam(); - mBodyAdapter.setData(mBodyBeautyBeans); - mModelAttributeRange = mDataFactory.getModelAttributeRange(); - BodyBeautyBean data = mBodyBeautyBeans.get(mBodyIndex); - double value = mDataFactory.getParamIntensity(data.getKey()); - double stand = mModelAttributeRange.get(data.getKey()).getStandV(); - double maxRange = mModelAttributeRange.get(data.getKey()).getMaxRange(); - seekToSeekBar(value, stand, maxRange); - setRecoverEnable(checkParamsChanged()); - } - - - private void initView() { - recyclerView = findViewById(R.id.recycler_view); - discreteSeekBar = findViewById(R.id.seek_bar); - recoverLayout = findViewById(R.id.lyt_beauty_recover); - recoverImageView = findViewById(R.id.iv_beauty_recover); - recoverTextView = findViewById(R.id.tv_beauty_recover); - switchCompat = findViewById(R.id.switch_compat); - initHorizontalRecycleView(recyclerView); - } - - private void initAdapter() { - mBodyAdapter = new BaseListAdapter<>(new ArrayList<>(), new BaseDelegate() { - @Override - public void convert(int viewType, BaseViewHolder helper, BodyBeautyBean data, int position) { - helper.setText(R.id.tv_control, data.getDesRes()); - double value = mDataFactory.getParamIntensity(data.getKey()); - double stand = mModelAttributeRange.get(data.getKey()).getStandV(); - if (DecimalUtils.doubleEquals(value, stand)) { - helper.setImageResource(R.id.iv_control, data.getCloseRes()); - } else { - helper.setImageResource(R.id.iv_control, data.getOpenRes()); - } - helper.itemView.setSelected(position == mBodyIndex); - } - - @Override - public void onItemClickListener(View view, BodyBeautyBean data, int position) { - if (mBodyIndex != position) { - changeAdapterSelected(mBodyAdapter, mBodyIndex, position); - mBodyIndex = position; - double value = mDataFactory.getParamIntensity(data.getKey()); - double stand = mModelAttributeRange.get(data.getKey()).getStandV(); - double maxRange = mModelAttributeRange.get(data.getKey()).getMaxRange(); - seekToSeekBar(value, stand, maxRange); - } - } - - }, R.layout.list_item_control_title_image_circle); - recyclerView.setAdapter(mBodyAdapter); - } - - private void bindListener() { - findViewById(R.id.cyt_main).setOnTouchListener((v, event) -> true); - discreteSeekBar.setOnProgressChangeListener(new DiscreteSeekBar.OnSimpleProgressChangeListener() { - - @Override - public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) { - if (!fromUser) { - return; - } - double valueF = 1.0 * (value - seekBar.getMin()) / 100; - BodyBeautyBean data = mBodyBeautyBeans.get(mBodyIndex); - double intensity = mDataFactory.getParamIntensity(data.getKey()); - double range = mModelAttributeRange.get(data.getKey()).getMaxRange(); - double res = valueF * range; - if (!DecimalUtils.doubleEquals(res, intensity)) { - mDataFactory.updateParamIntensity(data.getKey(), res); - setRecoverEnable(checkParamsChanged()); - updateBeautyItemUI(mBodyAdapter.getViewHolderByPosition(mBodyIndex), data); - } - } - }); - findViewById(R.id.lyt_beauty_recover).setOnClickListener((view) -> showDialog(mContext.getString(R.string.dialog_reset_avatar_model), () -> recoverData())); - switchCompat.setOnCheckedChangeListener((buttonView, isChecked) -> { - mDataFactory.enableBodyBeauty(isChecked); - - }); - } - - /** - * 设置滚动条数值 - */ - private void seekToSeekBar(double value, double stand, double range) { - if (stand == 0.5) { - discreteSeekBar.setMin(-50); - discreteSeekBar.setMax(50); - discreteSeekBar.setProgress((int) (value * 100 / range - 50)); - } else { - discreteSeekBar.setMin(0); - discreteSeekBar.setMax(100); - discreteSeekBar.setProgress((int) (value * 100 / range)); - } - discreteSeekBar.setVisibility(View.VISIBLE); - } - - /** - * 更新单项是否为基准值显示 - */ - private void updateBeautyItemUI(BaseViewHolder viewHolder, BodyBeautyBean bean) { - double value = mDataFactory.getParamIntensity(bean.getKey()); - double stand = mModelAttributeRange.get(bean.getKey()).getStandV(); - if (viewHolder == null) { - return; - } - if (DecimalUtils.doubleEquals(value, stand)) { - viewHolder.setImageResource(R.id.iv_control, bean.getCloseRes()); - } else { - viewHolder.setImageResource(R.id.iv_control, bean.getOpenRes()); - } - } - - /** - * 重置数据 - */ - private void recoverData() { - for (BodyBeautyBean bean : mBodyBeautyBeans) { - double intensity = mModelAttributeRange.get(bean.getKey()).getDefaultV(); - mDataFactory.updateParamIntensity(bean.getKey(), intensity); - } - BodyBeautyBean data = mBodyBeautyBeans.get(mBodyIndex); - double value = mDataFactory.getParamIntensity(data.getKey()); - double stand = mModelAttributeRange.get(data.getKey()).getStandV(); - double maxRange = mModelAttributeRange.get(data.getKey()).getMaxRange(); - seekToSeekBar(value, stand, maxRange); - mBodyAdapter.notifyDataSetChanged(); - setRecoverEnable(false); - } - - /** - * 遍历数据确认还原按钮是否可以点击 - * - * @return Boolean - */ - private boolean checkParamsChanged() { - BodyBeautyBean bean = mBodyBeautyBeans.get(mBodyIndex); - double value = mDataFactory.getParamIntensity(bean.getKey()); - double defaultV = mModelAttributeRange.get(bean.getKey()).getDefaultV(); - if (!DecimalUtils.doubleEquals(value, defaultV)) { - return true; - } - for (BodyBeautyBean beautyBean : mBodyBeautyBeans) { - value = mDataFactory.getParamIntensity(beautyBean.getKey()); - defaultV = mModelAttributeRange.get(beautyBean.getKey()).getDefaultV(); - if (!DecimalUtils.doubleEquals(value, defaultV)) { - return true; - } - } - return false; - } - - /** - * 重置还原按钮状态 - * - * @param enable Boolean - */ - private void setRecoverEnable(Boolean enable) { - if (enable) { - recoverImageView.setAlpha(1f); - recoverTextView.setAlpha(1f); - } else { - recoverImageView.setAlpha(0.6f); - recoverTextView.setAlpha(0.6f); - } - recoverLayout.setEnabled(enable); - } -} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.kt new file mode 100644 index 000000000..a4e949cdc --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/control/BodyBeautyControlView.kt @@ -0,0 +1,205 @@ +package com.yunbao.faceunity.control + +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.View +import com.faceunity.core.utils.DecimalUtils +import com.yunbao.faceunity.R +import com.yunbao.faceunity.base.BaseDelegate +import com.yunbao.faceunity.base.BaseListAdapter +import com.yunbao.faceunity.base.BaseViewHolder +import com.yunbao.faceunity.entity.BodyBeautyBean +import com.yunbao.faceunity.entity.ModelAttributeData +import com.yunbao.faceunity.infe.AbstractBodyBeautyDataFactory +import com.yunbao.faceunity.seekbar.DiscreteSeekBar + +import kotlinx.android.synthetic.main.layout_body_beauty_control.view.* + + +/** + * + * DESC:美体 + * Created on 2020/12/11 + * + */ +class BodyBeautyControlView @JvmOverloads constructor(private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + BaseControlView(mContext, attrs, defStyleAttr) { + private lateinit var mDataFactory: AbstractBodyBeautyDataFactory + private lateinit var mModelAttributeRange: HashMap + private lateinit var mBodyBeautyBeans: ArrayList + private lateinit var mBodyAdapter: BaseListAdapter + private var mBodyIndex = 0 + + // region init + + init { + LayoutInflater.from(context).inflate(R.layout.layout_body_beauty_control, this) + initView() + initAdapter() + bindListener() + } + + + fun bindDataFactory(dataFactory: AbstractBodyBeautyDataFactory) { + mDataFactory = dataFactory + mBodyBeautyBeans = mDataFactory.bodyBeautyParam + mBodyAdapter.setData(mBodyBeautyBeans) + mModelAttributeRange = mDataFactory.modelAttributeRange + val data = mBodyBeautyBeans[mBodyIndex] + val value = mDataFactory.getParamIntensity(data.key) + val stand = mModelAttributeRange[data.key]!!.stand + val maxRange = mModelAttributeRange[data.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + setRecoverEnable(checkParamsChanged()) + + } + + private fun initView() { + initHorizontalRecycleView(recycler_view) + } + + + private fun initAdapter() { + mBodyAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate() { + override fun convert(viewType: Int, helper: BaseViewHolder, data: BodyBeautyBean, position: Int) { + helper.setText(R.id.tv_control, data.desRes) + val value = mDataFactory.getParamIntensity(data.key) + val stand = mModelAttributeRange[data.key]!!.stand + if (DecimalUtils.doubleEquals(value, stand)) { + helper.setImageResource(R.id.iv_control, data.closeRes) + } else { + helper.setImageResource(R.id.iv_control, data.openRes) + } + helper.itemView.isSelected = position == mBodyIndex + } + + override fun onItemClickListener(view: View, data: BodyBeautyBean, position: Int) { + if (mBodyIndex != position) { + changeAdapterSelected(mBodyAdapter, mBodyIndex, position) + mBodyIndex = position + val value = mDataFactory.getParamIntensity(data.key) + val stand = mModelAttributeRange[data.key]!!.stand + val maxRange = mModelAttributeRange[data.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + } + } + + }, R.layout.list_item_control_title_image_circle) + recycler_view.adapter = mBodyAdapter + } + + private fun bindListener() { + cyt_main.setOnTouchListener { _, _ -> true } + beauty_seek_bar.setOnProgressChangeListener(object : DiscreteSeekBar.OnSimpleProgressChangeListener() { + override fun onProgressChanged(seekBar: DiscreteSeekBar?, value: Int, fromUser: Boolean) { + if (!fromUser) { + return + } + val valueF = 1.0 * (value - seekBar!!.min) / 100 + val data = mBodyBeautyBeans[mBodyIndex] + val value = mDataFactory.getParamIntensity(data.key) + val range = mModelAttributeRange[data.key]!!.maxRange + val res = valueF * range + if (!DecimalUtils.doubleEquals(res, value)) { + mDataFactory.updateParamIntensity(data.key, res) + setRecoverEnable(checkParamsChanged()) + updateBeautyItemUI(mBodyAdapter.getViewHolderByPosition(mBodyIndex), data) + } + } + }) + lyt_beauty_recover.setOnClickListener { + showDialog(mContext.getString(R.string.dialog_reset_avatar_model)) { + recoverData() + } + } + } + + + /** + * 设置滚动条数值 + */ + private fun seekToSeekBar(value: Double, stand: Double, range: Double) { + if (stand == 0.5) { + beauty_seek_bar.min = -50 + beauty_seek_bar.max = 50 + beauty_seek_bar.progress = (value * 100 / range - 50).toInt() + } else { + beauty_seek_bar.min = 0 + beauty_seek_bar.max = 100 + beauty_seek_bar.progress = (value * 100 / range).toInt() + } + beauty_seek_bar.visibility = View.VISIBLE + } + + + // endregion + + + /** + * 更新单项是否为基准值显示 + */ + private fun updateBeautyItemUI(viewHolder: BaseViewHolder?, data: BodyBeautyBean) { + val value = mDataFactory.getParamIntensity(data.key) + val stand = mModelAttributeRange[data.key]!!.stand + if (DecimalUtils.doubleEquals(value, stand)) { + viewHolder?.setImageResource(R.id.iv_control, data.closeRes) + } else { + viewHolder?.setImageResource(R.id.iv_control, data.openRes) + } + } + + + private fun recoverData() { + mBodyBeautyBeans.forEach { + val default = mModelAttributeRange[it.key]!!.default + mDataFactory.updateParamIntensity(it.key, default) + } + val data = mBodyBeautyBeans[mBodyIndex] + val value = mDataFactory.getParamIntensity(data.key) + val stand = mModelAttributeRange[data.key]!!.stand + val maxRange = mModelAttributeRange[data.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + mBodyAdapter.notifyDataSetChanged() + setRecoverEnable(false) + } + + /** + * 遍历数据确认还原按钮是否可以点击 + * @return Boolean + */ + private fun checkParamsChanged(): Boolean { + var item = mBodyBeautyBeans[mBodyIndex] + var value = mDataFactory.getParamIntensity(item.key) + var default = mModelAttributeRange[item.key]!!.default + if (!DecimalUtils.doubleEquals(value, default)) { + return true + } + mBodyBeautyBeans.forEach { + value = mDataFactory.getParamIntensity(it.key) + default = mModelAttributeRange[it.key]!!.default + if (!DecimalUtils.doubleEquals(value, default)) { + return true + } + } + return false + } + + + /** + * 重置还原按钮状态 + * @param enable Boolean + */ + private fun setRecoverEnable(enable: Boolean) { + if (enable) { + tv_beauty_recover.alpha = 1f + iv_beauty_recover.alpha = 1f + } else { + tv_beauty_recover.alpha = 0.6f + iv_beauty_recover.alpha = 0.6f + } + lyt_beauty_recover.isEnabled = enable + } + + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.java b/FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.java deleted file mode 100644 index fc688f8b8..000000000 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.java +++ /dev/null @@ -1,463 +0,0 @@ -package com.yunbao.faceunity.control; - -import android.animation.ValueAnimator; -import android.annotation.SuppressLint; -import android.content.Context; -import android.util.AttributeSet; -import android.view.LayoutInflater; -import android.view.View; -import android.widget.ImageView; -import android.widget.LinearLayout; -import android.widget.TextView; - -import androidx.annotation.NonNull; -import androidx.annotation.Nullable; -import androidx.appcompat.widget.SwitchCompat; -import androidx.recyclerview.widget.RecyclerView; - -import com.faceunity.core.utils.DecimalUtils; -import com.yunbao.faceunity.R; -import com.yunbao.faceunity.base.BaseDelegate; -import com.yunbao.faceunity.base.BaseListAdapter; -import com.yunbao.faceunity.base.BaseViewHolder; -import com.yunbao.faceunity.checkbox.CheckGroup; -import com.yunbao.faceunity.entity.FaceBeautyBean; -import com.yunbao.faceunity.entity.FaceBeautyFilterBean; -import com.yunbao.faceunity.entity.ModelAttributeData; -import com.yunbao.faceunity.infe.AbstractFaceBeautyDataFactory; -import com.yunbao.faceunity.seekbar.DiscreteSeekBar; - -import java.util.ArrayList; -import java.util.HashMap; - -/** - * DESC: - * Created on 2021/4/26 - */ -public class FaceBeautyControlView extends BaseControlView { - - private AbstractFaceBeautyDataFactory mDataFactory; - - /* 美颜、美型 */ - private HashMap mModelAttributeRange; - private ArrayList mSkinBeauty; - private ArrayList mShapeBeauty; - private int mSkinIndex = 0; - private int mShapeIndex = 1; - private BaseListAdapter mBeautyAdapter; - - /* 滤镜 */ - private ArrayList mFilters; - private BaseListAdapter mFiltersAdapter; - - - private RecyclerView recyclerView; - private DiscreteSeekBar discreteSeekBar; - private CheckGroup checkGroup; - private LinearLayout recoverLayout; - private ImageView recoverImageView; - private TextView recoverTextView; - private View lineView; - private LinearLayout bottomLayout; - private SwitchCompat switchCompat; - - public FaceBeautyControlView(@NonNull Context context) { - super(context); - init(); - } - - public FaceBeautyControlView(@NonNull Context context, @Nullable AttributeSet attrs) { - super(context, attrs); - init(); - } - - public FaceBeautyControlView(@NonNull Context context, @Nullable AttributeSet attrs, int defStyleAttr) { - super(context, attrs, defStyleAttr); - init(); - } - - - /** - * 给控制绑定FaceBeautyController,数据工厂 - * - * @param dataFactory IFaceBeautyDataFactory - */ - public void bindDataFactory(AbstractFaceBeautyDataFactory dataFactory) { - mDataFactory = dataFactory; - mModelAttributeRange = dataFactory.getModelAttributeRange(); - mSkinBeauty = dataFactory.getSkinBeauty(); - mShapeBeauty = dataFactory.getShapeBeauty(); - mFilters = dataFactory.getBeautyFilters(); - mFiltersAdapter.setData(mFilters); - checkGroup.check(View.NO_ID); - } - - - private void init() { - LayoutInflater.from(mContext).inflate(R.layout.layout_face_beauty_control, this); - initView(); - initAdapter(); - bindListener(); - - } - // region init - - private void initView() { - recyclerView = findViewById(R.id.recycler_view); - discreteSeekBar = findViewById(R.id.seek_bar); - checkGroup = findViewById(R.id.beauty_radio_group); - recoverLayout = findViewById(R.id.lyt_beauty_recover); - recoverImageView = findViewById(R.id.iv_beauty_recover); - recoverTextView = findViewById(R.id.tv_beauty_recover); - lineView = findViewById(R.id.iv_line); - bottomLayout = findViewById(R.id.fyt_bottom_view); - switchCompat = findViewById(R.id.switch_compat); - initHorizontalRecycleView(recyclerView); - } - - - /** - * 构造Adapter - */ - private void initAdapter() { - mFiltersAdapter = new BaseListAdapter<>( - new ArrayList<>(), new BaseDelegate() { - @Override - public void convert(int viewType, BaseViewHolder helper, FaceBeautyFilterBean data, int position) { - helper.setText(R.id.tv_control, data.getDesRes()); - helper.setImageResource(R.id.iv_control, data.getImageRes()); - helper.itemView.setSelected(mDataFactory.getCurrentFilterIndex() == position); - } - - @Override - public void onItemClickListener(View view, FaceBeautyFilterBean data, int position) { - if (mDataFactory.getCurrentFilterIndex() != position) { - changeAdapterSelected(mFiltersAdapter, mDataFactory.getCurrentFilterIndex(), position); - mDataFactory.setCurrentFilterIndex(position); - mDataFactory.onFilterSelected(data.getKey(), data.getIntensity(), data.getDesRes()); - if (position == 0) { - discreteSeekBar.setVisibility(View.INVISIBLE); - } else { - seekToSeekBar(data.getIntensity(), 0.0, 1.0); - } - } - - } - }, R.layout.list_item_control_title_image_square); - - - mBeautyAdapter = new BaseListAdapter<>(new ArrayList<>(), new BaseDelegate() { - @Override - public void convert(int viewType, BaseViewHolder helper, FaceBeautyBean data, int position) { - helper.setText(R.id.tv_control, data.getDesRes()); - double value = mDataFactory.getParamIntensity(data.getKey()); - double stand = mModelAttributeRange.get(data.getKey()).getStandV(); - if (DecimalUtils.doubleEquals(value, stand)) { - helper.setImageResource(R.id.iv_control, data.getCloseRes()); - } else { - helper.setImageResource(R.id.iv_control, data.getOpenRes()); - } - boolean isShinSelected = checkGroup.getCheckedCheckBoxId() == R.id.beauty_radio_skin_beauty; - helper.itemView.setSelected(isShinSelected ? mSkinIndex == position : mShapeIndex == position); - } - - @Override - public void onItemClickListener(View view, FaceBeautyBean data, int position) { - boolean isShinSelected = checkGroup.getCheckedCheckBoxId() == R.id.beauty_radio_skin_beauty; - if ((isShinSelected && position == mSkinIndex) || (!isShinSelected && position == mShapeIndex)) { - return; - } - if (isShinSelected) { - changeAdapterSelected(mBeautyAdapter, mSkinIndex, position); - mSkinIndex = position; - } else { - changeAdapterSelected(mBeautyAdapter, mShapeIndex, position); - mShapeIndex = position; - } - double value = mDataFactory.getParamIntensity(data.getKey()); - double stand = mModelAttributeRange.get(data.getKey()).getStandV(); - double maxRange = mModelAttributeRange.get(data.getKey()).getMaxRange(); - seekToSeekBar(value, stand, maxRange); - } - }, R.layout.list_item_control_title_image_circle); - } - - - /** - * 绑定监听事件 - */ - @SuppressLint("ClickableViewAccessibility") - private void bindListener() { - /*拦截触碰事件*/ - findViewById(R.id.fyt_bottom_view).setOnTouchListener((v, event) -> true); - /*菜单控制*/ - bindBottomRadioListener(); - /*滑动条控制*/ - bindSeekBarListener(); - /*还原数据*/ - recoverLayout.setOnClickListener((view) -> showDialog(mContext.getString(R.string.dialog_reset_avatar_model), () -> recoverData())); - /*渲染开关*/ - switchCompat.setOnCheckedChangeListener((buttonView, isChecked) -> mDataFactory.enableFaceBeauty(isChecked)); - } - - - /** - * 滚动条绑定事件 - */ - private void bindSeekBarListener() { - discreteSeekBar.setOnProgressChangeListener(new DiscreteSeekBar.OnSimpleProgressChangeListener() { - @Override - public void onProgressChanged(DiscreteSeekBar seekBar, int value, boolean fromUser) { - if (!fromUser) { - return; - } - double valueF = 1.0 * (value - seekBar.getMin()) / 100; - if (checkGroup.getCheckedCheckBoxId() == R.id.beauty_radio_skin_beauty) { - FaceBeautyBean bean = mSkinBeauty.get(mSkinIndex); - double range = mModelAttributeRange.get(bean.getKey()).getMaxRange(); - double res = valueF * range; - double intensity = mDataFactory.getParamIntensity(bean.getKey()); - if (!DecimalUtils.doubleEquals(res, intensity)) { - mDataFactory.updateParamIntensity(bean.getKey(), res); - setRecoverEnable(checkFaceSkinChanged()); - updateBeautyItemUI(mBeautyAdapter.getViewHolderByPosition(mSkinIndex), bean); - } - } else if (checkGroup.getCheckedCheckBoxId() == R.id.beauty_radio_face_shape) { - FaceBeautyBean bean = mShapeBeauty.get(mShapeIndex); - double range = mModelAttributeRange.get(bean.getKey()).getMaxRange(); - double res = valueF * range; - double intensity = mDataFactory.getParamIntensity(bean.getKey()); - if (!DecimalUtils.doubleEquals(res, intensity)) { - mDataFactory.updateParamIntensity(bean.getKey(), res); - setRecoverEnable(checkFaceShapeChanged()); - updateBeautyItemUI(mBeautyAdapter.getViewHolderByPosition(mShapeIndex), bean); - } - } else if (checkGroup.getCheckedCheckBoxId() == R.id.beauty_radio_filter) { - FaceBeautyFilterBean bean = mFilters.get(mDataFactory.getCurrentFilterIndex()); - if (!DecimalUtils.doubleEquals(bean.getIntensity(), valueF)) { - bean.setIntensity(valueF); - mDataFactory.updateFilterIntensity(valueF); - } - } - } - }); - } - - /** - * 底部导航栏绑定监听事件,处理RecycleView等相关布局变更 - */ - private void bindBottomRadioListener() { - checkGroup.setOnCheckedChangeListener((group, checkedId) -> { - if (checkedId == R.id.beauty_radio_skin_beauty || checkedId == R.id.beauty_radio_face_shape) { - discreteSeekBar.setVisibility(View.VISIBLE); - recoverLayout.setVisibility(View.VISIBLE); - lineView.setVisibility(View.VISIBLE); - switchCompat.setVisibility(View.VISIBLE); - } else if (checkedId == R.id.beauty_radio_filter) { - discreteSeekBar.setVisibility((mDataFactory.getCurrentFilterIndex() == 0) ? View.INVISIBLE : View.VISIBLE); - recoverLayout.setVisibility(View.GONE); - lineView.setVisibility(View.GONE); - switchCompat.setVisibility(View.VISIBLE); - } else if (checkedId == View.NO_ID) { - mDataFactory.enableFaceBeauty(true); - switchCompat.setVisibility(View.INVISIBLE); - } - if (checkedId == R.id.beauty_radio_skin_beauty) { - mBeautyAdapter.setData(mSkinBeauty); - recyclerView.setAdapter(mBeautyAdapter); - FaceBeautyBean item = mSkinBeauty.get(mSkinIndex); - double value = mDataFactory.getParamIntensity(item.getKey()); - double stand = mModelAttributeRange.get(item.getKey()).getStandV(); - double maxRange = mModelAttributeRange.get(item.getKey()).getMaxRange(); - seekToSeekBar(value, stand, maxRange); - setRecoverEnable(checkFaceSkinChanged()); - changeBottomLayoutAnimator(true); - } else if (checkedId == R.id.beauty_radio_face_shape) { - mBeautyAdapter.setData(mShapeBeauty); - recyclerView.setAdapter(mBeautyAdapter); - FaceBeautyBean item = mShapeBeauty.get(mShapeIndex); - double value = mDataFactory.getParamIntensity(item.getKey()); - double stand = mModelAttributeRange.get(item.getKey()).getStandV(); - double maxRange = mModelAttributeRange.get(item.getKey()).getMaxRange(); - seekToSeekBar(value, stand, maxRange); - setRecoverEnable(checkFaceShapeChanged()); - changeBottomLayoutAnimator(true); - } else if (checkedId == R.id.beauty_radio_filter) { - recyclerView.setAdapter(mFiltersAdapter); - recyclerView.scrollToPosition(mDataFactory.getCurrentFilterIndex()); - if (mDataFactory.getCurrentFilterIndex() == 0) { - discreteSeekBar.setVisibility(View.INVISIBLE); - } else { - seekToSeekBar(mFilters.get(mDataFactory.getCurrentFilterIndex()).getIntensity(), 0.0, 1.0); - } - changeBottomLayoutAnimator(true); - } else if (checkedId == View.NO_ID) { - changeBottomLayoutAnimator(false); - mDataFactory.enableFaceBeauty(true); - } - }); - } - // endregion - // region 业务处理 - - /** - * 设置滚动条数值 - * - * @param value Double 结果值 - * @param stand Double 标准值 - * @param range Double 范围区间 - */ - private void seekToSeekBar(double value, double stand, double range) { - if (stand == 0.5) { - discreteSeekBar.setMin(-50); - discreteSeekBar.setMax(50); - discreteSeekBar.setProgress((int) (value * 100 / range - 50)); - } else { - discreteSeekBar.setMin(0); - discreteSeekBar.setMax(100); - discreteSeekBar.setProgress((int) (value * 100 / range)); - } - discreteSeekBar.setVisibility(View.VISIBLE); - } - - /** - * 更新单项是否为基准值显示 - */ - private void updateBeautyItemUI(BaseViewHolder viewHolder, FaceBeautyBean bean) { - double value = mDataFactory.getParamIntensity(bean.getKey()); - double stand = mModelAttributeRange.get(bean.getKey()).getStandV(); - if (viewHolder == null) { - return; - } - if (DecimalUtils.doubleEquals(value, stand)) { - viewHolder.setImageResource(R.id.iv_control, bean.getCloseRes()); - } else { - viewHolder.setImageResource(R.id.iv_control, bean.getOpenRes()); - } - } - - /** - * 重置还原按钮状态 - * - * @param enable Boolean - */ - private void setRecoverEnable(Boolean enable) { - if (enable) { - recoverImageView.setAlpha(1f); - recoverTextView.setAlpha(1f); - } else { - recoverImageView.setAlpha(0.6f); - recoverTextView.setAlpha(0.6f); - } - recoverLayout.setEnabled(enable); - } - - - /** - * 遍历美肤数据确认还原按钮是否可以点击 - * - * @return Boolean - */ - private boolean checkFaceSkinChanged() { - FaceBeautyBean bean = mSkinBeauty.get(mSkinIndex); - double value = mDataFactory.getParamIntensity(bean.getKey()); - double defaultV = mModelAttributeRange.get(bean.getKey()).getDefaultV(); - if (!DecimalUtils.doubleEquals(value, defaultV)) { - return true; - } - for (FaceBeautyBean beautyBean : mSkinBeauty) { - value = mDataFactory.getParamIntensity(beautyBean.getKey()); - defaultV = mModelAttributeRange.get(beautyBean.getKey()).getDefaultV(); - if (!DecimalUtils.doubleEquals(value, defaultV)) { - return true; - } - } - return false; - } - - /** - * 遍历美型数据确认还原按钮是否可以点击 - * - * @return Boolean - */ - private boolean checkFaceShapeChanged() { - FaceBeautyBean bean = mShapeBeauty.get(mShapeIndex); - double value = mDataFactory.getParamIntensity(bean.getKey()); - double defaultV = mModelAttributeRange.get(bean.getKey()).getDefaultV(); - if (!DecimalUtils.doubleEquals(value, defaultV)) { - return true; - } - for (FaceBeautyBean beautyBean : mShapeBeauty) { - value = mDataFactory.getParamIntensity(beautyBean.getKey()); - defaultV = mModelAttributeRange.get(beautyBean.getKey()).getDefaultV(); - if (!DecimalUtils.doubleEquals(value, defaultV)) { - return true; - } - } - return false; - } - - /** - * 还原 美型、美肤数据 - */ - private void recoverData() { - if (checkGroup.getCheckedCheckBoxId() == R.id.beauty_radio_skin_beauty) { - recoverData(mSkinBeauty, mSkinIndex); - } else if (checkGroup.getCheckedCheckBoxId() == R.id.beauty_radio_face_shape) { - recoverData(mShapeBeauty, mShapeIndex); - } - } - - /** - * 重置数据 - * - * @param beautyBeans - * @param currentIndex - */ - private void recoverData(ArrayList beautyBeans, int currentIndex) { - for (FaceBeautyBean bean : beautyBeans) { - double intensity = mModelAttributeRange.get(bean.getKey()).getDefaultV(); - mDataFactory.updateParamIntensity(bean.getKey(), intensity); - } - FaceBeautyBean data = beautyBeans.get(currentIndex); - double value = mDataFactory.getParamIntensity(data.getKey()); - double stand = mModelAttributeRange.get(data.getKey()).getStandV(); - double maxRange = mModelAttributeRange.get(data.getKey()).getMaxRange(); - seekToSeekBar(value, stand, maxRange); - mBeautyAdapter.notifyDataSetChanged(); - setRecoverEnable(false); - } - - /** - * 底部动画处理 - * - * @param isOpen Boolean - */ - private void changeBottomLayoutAnimator(boolean isOpen) { - if (isBottomShow == isOpen) { - return; - } - int start = isOpen ? getResources().getDimensionPixelSize(R.dimen.x1) : getResources().getDimensionPixelSize(R.dimen.x268); - int end = isOpen ? getResources().getDimensionPixelSize(R.dimen.x268) : getResources().getDimensionPixelSize(R.dimen.x1); - if (bottomLayoutAnimator != null && bottomLayoutAnimator.isRunning()) { - bottomLayoutAnimator.end(); - } - bottomLayoutAnimator = ValueAnimator.ofInt(start, end).setDuration(150); - bottomLayoutAnimator.addUpdateListener(animation -> { - int height = (int) animation.getAnimatedValue(); - LinearLayout.LayoutParams params = (LinearLayout.LayoutParams) bottomLayout.getLayoutParams(); - params.height = height; - bottomLayout.setLayoutParams(params); - if (onBottomAnimatorChangeListener != null) { - float showRate = 1.0f * (height - start) / (end - start); - onBottomAnimatorChangeListener.onBottomAnimatorChangeListener(isOpen ? showRate : 1 - showRate); - } - if (DecimalUtils.floatEquals(animation.getAnimatedFraction(), 1.0f) && isOpen) { - switchCompat.setVisibility(View.VISIBLE); - } - }); - bottomLayoutAnimator.start(); - isBottomShow = isOpen; - } - -} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.kt new file mode 100644 index 000000000..79e1eafd3 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/control/FaceBeautyControlView.kt @@ -0,0 +1,826 @@ +package com.yunbao.faceunity.control + +import android.animation.ValueAnimator +import android.content.Context +import android.util.AttributeSet +import android.view.LayoutInflater +import android.view.MotionEvent +import android.view.View +import android.view.animation.AlphaAnimation +import android.view.animation.Animation +import android.view.animation.AnimationSet +import android.view.animation.TranslateAnimation +import android.widget.ImageView +import android.widget.LinearLayout +import com.faceunity.core.utils.DecimalUtils +import com.yunbao.faceunity.R +import com.yunbao.faceunity.base.BaseDelegate +import com.yunbao.faceunity.base.BaseListAdapter +import com.yunbao.faceunity.base.BaseViewHolder +import com.yunbao.faceunity.dialog.ToastHelper +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.seekbar.DiscreteSeekBar +import kotlinx.android.synthetic.main.layout_face_beauty_control.view.* +import kotlin.collections.set + + +/** + * + * DESC:美颜 + * Created on 2020/11/17 + * + */ +class FaceBeautyControlView @JvmOverloads constructor(private val mContext: Context, attrs: AttributeSet? = null, defStyleAttr: Int = 0) : + BaseControlView(mContext, attrs, defStyleAttr) { + + private lateinit var mDataFactory: AbstractFaceBeautyDataFactory + + /* 美颜、美型 */ + private lateinit var mModelAttributeRange: HashMap + private var mSkinBeauty = ArrayList() + private var mShapeBeauty = ArrayList() + private var mShapeBeautySubItem = ArrayList() + private var mSubItemUIValueCache: HashMap = HashMap()//美型子项脸型的UI缓存值 + private var mSkinIndex = 0 + private var mShapeIndex = 1 + private var mIsOnBeautyShapeMain = true//美型是否在主项上 + + private lateinit var mBeautyAdapter: BaseListAdapter + + /* 滤镜 */ + private var mFilters = ArrayList() + private lateinit var mFiltersAdapter: BaseListAdapter + + /* 风格 */ + private var mStyles = ArrayList() + private lateinit var mStylesAdapter: BaseListAdapter + private var mEnableBottomRationClick = true + // region init + + init { + LayoutInflater.from(context).inflate(R.layout.layout_face_beauty_control, this) + initView() + initAdapter() + bindListener() + } + + + /** + * 给控制绑定FaceBeautyController,数据工厂 + * @param dataFactory IFaceBeautyDataFactory + */ + fun bindDataFactory(dataFactory: AbstractFaceBeautyDataFactory) { + mDataFactory = dataFactory + mModelAttributeRange = dataFactory.modelAttributeRange + mSkinBeauty = dataFactory.skinBeauty + mShapeBeauty = dataFactory.shapeBeauty + mShapeBeautySubItem = dataFactory.shapeBeautySubItem + mFilters = dataFactory.beautyFilters + mStyles = dataFactory.beautyStyles + mFiltersAdapter.setData(mFilters) + mStylesAdapter.setData(mStyles) + if (dataFactory.currentStyleIndex > -1) { + lyt_style_recover.isSelected = false + setBottomCheckRatioEnable(false) + var data = mStyles[dataFactory.currentStyleIndex] + mDataFactory.onStyleSelected(data.key) + } else { + lyt_style_recover.isSelected = true + setBottomCheckRatioEnable(true) + } + beauty_radio_group.check(View.NO_ID) + + //恢复上一次脸型选项的UI值 + mSubItemUIValueCache = mDataFactory.getCurrentFaceShapeUIValue() + } + + /** + * 收回菜单栏 + */ + fun hideControlView() { + beauty_radio_group.check(View.NO_ID) + } + + + /** + * View初始化 + */ + private fun initView() { + initHorizontalRecycleView(recycler_view) + } + + + /** + * 构造Adapter + */ + private fun initAdapter() { + mStylesAdapter = BaseListAdapter( + ArrayList(), object : BaseDelegate() { + override fun convert(viewType: Int, helper: BaseViewHolder, data: FaceBeautyStyleBean, position: Int) { + helper.setText(R.id.tv_control, data.desRes) + helper.setImageResource(R.id.iv_control, data.imageRes) + helper.itemView.isSelected = mDataFactory.currentStyleIndex == position + } + + override fun onItemClickListener(view: View, data: FaceBeautyStyleBean, position: Int) { + super.onItemClickListener(view, data, position) + if (mDataFactory.currentStyleIndex != position) { + lyt_style_recover.isSelected = false + setBottomCheckRatioEnable(false) + changeAdapterSelected(mStylesAdapter, mDataFactory.currentStyleIndex, position) + mDataFactory.currentStyleIndex = position + mDataFactory.onStyleSelected(data.key) + } + } + }, R.layout.list_item_control_title_image_circle + ) + + mFiltersAdapter = BaseListAdapter( + ArrayList(), object : BaseDelegate() { + override fun convert(viewType: Int, helper: BaseViewHolder, data: FaceBeautyFilterBean, position: Int) { + helper.setText(R.id.tv_control, data.desRes) + helper.setImageResource(R.id.iv_control, data.imageRes) + helper.itemView.isSelected = mDataFactory.currentFilterIndex == position + } + + override fun onItemClickListener(view: View, data: FaceBeautyFilterBean, position: Int) { + super.onItemClickListener(view, data, position) + if (mDataFactory.currentFilterIndex != position) { + changeAdapterSelected(mFiltersAdapter, mDataFactory.currentFilterIndex, position) + mDataFactory.currentFilterIndex = position + mDataFactory.onFilterSelected(data.key, data.intensity, data.desRes) + if (position == 0) { + beauty_seek_bar.visibility = View.INVISIBLE + } else { + seekToSeekBar(data.intensity, 0.0, 1.0) + } + } + } + }, R.layout.list_item_control_title_image_square + ) + + mBeautyAdapter = BaseListAdapter(ArrayList(), object : BaseDelegate() { + override fun convert(viewType: Int, helper: BaseViewHolder, data: FaceBeautyBean, position: Int) { + val isShinSelected = beauty_radio_group.checkedCheckBoxId == R.id.beauty_radio_skin_beauty + helper.itemView.isSelected = if (isShinSelected) mSkinIndex == position else mShapeIndex == position + helper.setText(R.id.tv_control, data.desRes) + //主项的时候才需要显示 +// helper.setVisible(R.id.iv_oval_spot, !isShinSelected && mIsOnBeautyShapeMain && position ==0) + val value = mDataFactory.getParamIntensity(data.key) + when (data.buttonType) { + FaceBeautyBean.ButtonType.BACK_BUTTON -> { + helper.setImageResource(R.id.iv_control, data.closeRes) + } + FaceBeautyBean.ButtonType.SUB_ITEM_BUTTON -> { + //判断当前UI值 和 真实值是否全是空的如果是空的则不选中 + //先过UI值 + var choose = false + run outside@{ + mSubItemUIValueCache.forEach { + if (it.value > 0) { + choose = true + } + } + + mShapeBeautySubItem.forEach { + if (it.buttonType == FaceBeautyBean.ButtonType.NORMAL_BUTTON) { + if (mDataFactory.getParamIntensity(it.key) > 0) { + choose = true + } + } + } + } + + helper.setImageResource(R.id.iv_control, if (choose) data.openRes else data.closeRes) + } + //普通按钮 + else -> { + val stand = mModelAttributeRange[data.key]!!.stand + if (DecimalUtils.doubleEquals(value, stand)) { + helper.setImageResource(R.id.iv_control, data.closeRes) + } else { + helper.setImageResource(R.id.iv_control, data.openRes) + } + if (!data.canUseFunction) { + val ivControl = helper.getView(R.id.iv_control) + ivControl?.imageAlpha = 154 + } else { + val ivControl = helper.getView(R.id.iv_control) + ivControl?.imageAlpha = 255 + } + + if (openEnterAnimation && needEnterAnimation && position != 0) { + enterAnimation(helper.itemView) + if (position >=4 || (mBeautyAdapter.itemCount < 5 && position == mBeautyAdapter.itemCount - 1)) { + needEnterAnimation = false + } + } + } + } + } + + override fun onItemClickListener(view: View, data: FaceBeautyBean, position: Int) { + val isShinSelected = beauty_radio_group.checkedCheckBoxId == R.id.beauty_radio_skin_beauty + if ((isShinSelected && position == mSkinIndex) || (!isShinSelected && position == mShapeIndex)) { + return + } + if (!data.canUseFunction) { + ToastHelper.showNormalToast(mContext,data.toastDesRes) + return + } + if (isShinSelected) { + changeAdapterSelected(mBeautyAdapter, mSkinIndex, position) + val value = mDataFactory.getParamIntensity(data.key) + val stand = mModelAttributeRange[data.key]!!.stand + val maxRange = mModelAttributeRange[data.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + mSkinIndex = position + } else { + when (data.buttonType) { + FaceBeautyBean.ButtonType.BACK_BUTTON -> { + //返回按钮 + mBeautyAdapter.setData(mShapeBeauty) + //没有按钮被选中,需要隐藏进度条 + beauty_seek_bar.visibility = View.INVISIBLE + changeAdapterSelected(mBeautyAdapter, mShapeIndex, -1) + mShapeIndex = -1 + mIsOnBeautyShapeMain = true + needEnterAnimation = true + } + FaceBeautyBean.ButtonType.SUB_ITEM_BUTTON -> { + //子项按钮 + //选中的是哪一个子项 -> 在FaceBeauty中有记录 + run outside@{ + mShapeBeautySubItem.forEachIndexed{ index, value -> + if (mDataFactory.getCurrentOneHotFaceShape() == value.key) {//获取当前作用的脸型 + mShapeIndex = index + return@outside + } + } + } + + mBeautyAdapter.setData(mShapeBeautySubItem) + if (mShapeBeautySubItem.size >= 1) { + beauty_seek_bar.visibility = View.VISIBLE + val faceBeautyBean = mShapeBeautySubItem[mShapeIndex] + if (faceBeautyBean.buttonType == FaceBeautyBean.ButtonType.NORMAL_BUTTON) { + val value = mDataFactory.getParamIntensity(faceBeautyBean.key) + val stand = mModelAttributeRange[faceBeautyBean.key]!!.stand + val maxRange = mModelAttributeRange[faceBeautyBean.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + } + } + mIsOnBeautyShapeMain = false + needEnterAnimation = true + } + //普通按钮 + else -> { + //点击的是子项普通按钮还是主项普通按钮1.子项普通之间按钮效果One Hot 2.主项普通按钮之间效果可叠加 + beauty_seek_bar.visibility = View.VISIBLE + changeAdapterSelected(mBeautyAdapter, mShapeIndex, position) + //判断一下是子项还是主项,1.主项直接设置改点击对象的值,2.子项需要获取之前的缓存如果存在缓存设置回之前的值,然后还要将上一个点击过的子项sdk值设置为零,UI值进行缓存 + var value:Double + if (mIsOnBeautyShapeMain) { + value = mDataFactory.getParamIntensity(data.key) + } else { + //子项 one hot + 如果有UI值显示UI值 -> 并将UI缓存值设置到SDK + value = if (mSubItemUIValueCache.contains(data.key)) { + var value = mSubItemUIValueCache[data.key]!! + mDataFactory.updateParamIntensity(data.key, value) + mSubItemUIValueCache.remove(data.key)!! + } else + mDataFactory.getParamIntensity(data.key) + //将上一个点击的有效项设置为空 + if (mShapeIndex >= 0) { + var beforeData = mBeautyAdapter.getData(mShapeIndex) + when (beforeData.buttonType) { + FaceBeautyBean.ButtonType.NORMAL_BUTTON -> { + //算法值要设置为零,但是点击回来的时候需要根据UI值(缓存值)重新设置回算法值 + mSubItemUIValueCache[beforeData.key] = mDataFactory.getParamIntensity(beforeData.key) + mDataFactory.updateParamIntensity(beforeData.key,0.0) + } + } + } + mDataFactory.setCurrentOneHotFaceShape(data.key) + mBeautyAdapter.notifyItemChanged(mShapeIndex) + mBeautyAdapter.notifyItemChanged(position) + } + + //设置当前点击bean的进度值 + val stand = mModelAttributeRange[data.key]!!.stand + val maxRange = mModelAttributeRange[data.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + mShapeIndex = position + } + } + } + + } + }, R.layout.list_item_control_title_image_circle) + } + + + /** + * 绑定监听事件 + */ + private fun bindListener() { + /*拦截触碰事件*/ + fyt_bottom_view.setOnTouchListener { _, _ -> true } + /*菜单控制*/ + bindBottomRadioListener() + /*滑动条控制*/ + bindSeekBarListener() + /*比对开关*/ + iv_compare.setOnTouchStateListener { v, event -> + val action = event.action + if (action == MotionEvent.ACTION_DOWN) { + v.alpha = 0.7f + mDataFactory.enableFaceBeauty(false) + } else if (action == MotionEvent.ACTION_UP) { + v.alpha = 1f + mDataFactory.enableFaceBeauty(true) + } + true + } + /*还原数据*/ + lyt_beauty_recover.setOnClickListener { + showDialog(mContext.getString(R.string.dialog_reset_avatar_model)) { recoverData() } + + } + lyt_style_recover.setOnClickListener { + if (it.isSelected) { + return@setOnClickListener + } + changeAdapterSelected(mStylesAdapter, mDataFactory.currentStyleIndex, -1) + mDataFactory.currentStyleIndex = -1 + it.isSelected = true + setBottomCheckRatioEnable(true) + mDataFactory.onStyleSelected(null) + } + + iv_reset.setOnClickListener { + mDataFactory.resetParamIntensity() + var item:FaceBeautyBean? = null + when (beauty_radio_group.checkedCheckBoxId) { + R.id.beauty_radio_skin_beauty -> { + mBeautyAdapter.notifyDataSetChanged() + item = mSkinBeauty[mSkinIndex] + setRecoverFaceSkinEnable(true) + } + R.id.beauty_radio_face_shape -> { + mBeautyAdapter.notifyDataSetChanged() + item = mShapeBeauty[mShapeIndex] + setRecoverFaceSkinEnable(true) + } + R.id.beauty_radio_filter -> { + mFiltersAdapter.notifyDataSetChanged() + beauty_seek_bar.visibility = View.INVISIBLE + } + R.id.beauty_radio_style -> { + mStylesAdapter.notifyDataSetChanged() + } + } + item?.let { + val value = mDataFactory.getParamIntensity(it.key) + val stand = mModelAttributeRange[it.key]!!.stand + val maxRange = mModelAttributeRange[it.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + } + } + } + + + /** + * 滚动条绑定事件 + */ + private fun bindSeekBarListener() { + beauty_seek_bar.setOnProgressChangeListener(object : DiscreteSeekBar.OnSimpleProgressChangeListener() { + override fun onProgressChanged(seekBar: DiscreteSeekBar?, value: Int, fromUser: Boolean) { + if (!fromUser) { + return + } + val valueF = 1.0 * (value - seekBar!!.min) / 100 + when (beauty_radio_group.checkedCheckBoxId) { + R.id.beauty_radio_skin_beauty -> { + val bean = mSkinBeauty[mSkinIndex] + val range = mModelAttributeRange[bean.key]!!.maxRange + val res = valueF * range + val value = mDataFactory.getParamIntensity(bean.key) + if (!DecimalUtils.doubleEquals(res, value)) { + mDataFactory.updateParamIntensity(bean.key, res) + setRecoverFaceSkinEnable(checkFaceSkinChanged()) + updateBeautyItemUI(mBeautyAdapter.getViewHolderByPosition(mSkinIndex), bean) + } + } + R.id.beauty_radio_face_shape -> { + if (mShapeIndex < 0) return + val bean = mBeautyAdapter.getData(mShapeIndex) + when (bean.buttonType) { + FaceBeautyBean.ButtonType.NORMAL_BUTTON -> { + //判断一下这个按钮的类型 + val range = mModelAttributeRange[bean.key]!!.maxRange + val res = valueF * range + val value = mDataFactory.getParamIntensity(bean.key) + if (!DecimalUtils.doubleEquals(res, value)) { + mDataFactory.updateParamIntensity(bean.key, res) + setRecoverFaceSkinEnable(checkFaceShapeChanged()) + updateBeautyItemUI(mBeautyAdapter.getViewHolderByPosition(mShapeIndex), bean) + } + } + } + } + R.id.beauty_radio_filter -> { + val bean = mFilters[mDataFactory.currentFilterIndex] + if (!DecimalUtils.doubleEquals(bean.intensity, valueF)) { + bean.intensity = valueF + mDataFactory.updateFilterIntensity(valueF) + } + } + } + } + }) + } + + + /** + * 底部导航栏绑定监听事件,处理RecycleView等相关布局变更 + */ + private fun bindBottomRadioListener() { + beauty_radio_group.setOnDispatchActionUpListener { x -> + if (!mEnableBottomRationClick) { + val width = beauty_radio_group.measuredWidth + when { + x < width * 0.25 -> { + val toastStr = mContext.getString(R.string.beauty_face_style_toast, mContext.getString(R.string.beauty_radio_skin_beauty)) + ToastHelper.showNormalToast(mContext, toastStr) + } + x < width * 0.5 -> { + val toastStr = mContext.getString(R.string.beauty_face_style_toast, mContext.getString(R.string.beauty_radio_face_shape)) + ToastHelper.showNormalToast(mContext, toastStr) + } + x < width * 0.75f -> { + val toastStr = mContext.getString(R.string.beauty_face_style_toast, mContext.getString(R.string.beauty_radio_filter)) + ToastHelper.showNormalToast(mContext, toastStr) + } + } + } + } + + beauty_radio_group.setOnCheckedChangeListener { _, checkedId -> + //视图变化 + when (checkedId) { + R.id.beauty_radio_skin_beauty, R.id.beauty_radio_face_shape -> { + iv_compare.visibility = View.VISIBLE + beauty_seek_bar.visibility = View.VISIBLE + lyt_style_recover.visibility = View.GONE + lyt_beauty_recover.visibility = View.VISIBLE + iv_line.visibility = View.VISIBLE + } + R.id.beauty_radio_filter -> { + iv_compare.visibility = View.VISIBLE + beauty_seek_bar.visibility = if (mDataFactory.currentFilterIndex == 0) View.INVISIBLE else View.VISIBLE + lyt_style_recover.visibility = View.GONE + lyt_beauty_recover.visibility = View.GONE + iv_line.visibility = View.GONE + } + R.id.beauty_radio_style -> { + iv_compare.visibility = View.VISIBLE + beauty_seek_bar.visibility = View.INVISIBLE + lyt_beauty_recover.visibility = View.GONE + lyt_style_recover.visibility = View.VISIBLE + iv_line.visibility = View.VISIBLE + } + View.NO_ID -> { + iv_compare.visibility = View.INVISIBLE + mDataFactory.enableFaceBeauty(true) + } + } + + //数据变化 + when (checkedId) { + R.id.beauty_radio_skin_beauty -> { + mBeautyAdapter.setData(mSkinBeauty) + recycler_view.adapter = mBeautyAdapter + val item = mSkinBeauty[mSkinIndex] + val value = mDataFactory.getParamIntensity(item.key) + val stand = mModelAttributeRange[item.key]!!.stand + val maxRange = mModelAttributeRange[item.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + setRecoverFaceSkinEnable(checkFaceSkinChanged()) + changeBottomLayoutAnimator(true) + } + R.id.beauty_radio_face_shape -> { + mBeautyAdapter.setData(mShapeBeauty) + recycler_view.adapter = mBeautyAdapter + if (mShapeIndex >= 0) { + val item = mShapeBeauty[mShapeIndex] + val value = mDataFactory.getParamIntensity(item.key) + val stand = mModelAttributeRange[item.key]!!.stand + val maxRange = mModelAttributeRange[item.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + setRecoverFaceSkinEnable(checkFaceShapeChanged()) + changeBottomLayoutAnimator(true) + } else { + beauty_seek_bar.visibility = View.INVISIBLE + } + } + R.id.beauty_radio_filter -> { + recycler_view.adapter = mFiltersAdapter + recycler_view.scrollToPosition(mDataFactory.currentFilterIndex) + if (mDataFactory.currentFilterIndex == 0) { + beauty_seek_bar.visibility = View.INVISIBLE + } else { + seekToSeekBar(mFilters[mDataFactory.currentFilterIndex].intensity, 0.0, 1.0) + } + changeBottomLayoutAnimator(true) + } + R.id.beauty_radio_style -> { + recycler_view.adapter = mStylesAdapter + if (mDataFactory.currentStyleIndex > -1) { + recycler_view.scrollToPosition(mDataFactory.currentStyleIndex) + lyt_style_recover.isSelected = false + } else { + lyt_style_recover.isSelected = true + } + changeBottomLayoutAnimator(true) + } + View.NO_ID -> { + changeBottomLayoutAnimator(false) + mDataFactory.enableFaceBeauty(true) + } + + } + } + } + + + private fun setBottomCheckRatioEnable(enable: Boolean) { + mEnableBottomRationClick = enable + var i = 0 + val childCount: Int = beauty_radio_group.getChildCount() + while (i < childCount) { + val view: View = beauty_radio_group.getChildAt(i) + if (view.id != R.id.beauty_radio_style) { + view.alpha = if (enable) 1f else 0.6f + view.isEnabled = enable + } + i++ + } + } + + // endregion + // region 业务处理 + + + /** + * 设置滚动条数值 + * @param value Double 结果值 + * @param stand Double 标准值 + * @param range Double 范围区间 + */ + private fun seekToSeekBar(value: Double, stand: Double, range: Double) { + if (stand == 0.5) { + beauty_seek_bar.min = -50 + beauty_seek_bar.max = 50 + beauty_seek_bar.progress = (value * 100 / range - 50).toInt() + } else { + beauty_seek_bar.min = 0 + beauty_seek_bar.max = 100 + beauty_seek_bar.progress = (value * 100 / range).toInt() + } + beauty_seek_bar.visibility = View.VISIBLE + } + + /** + * 更新单项是否为基准值显示 + */ + private fun updateBeautyItemUI(viewHolder: BaseViewHolder?, item: FaceBeautyBean) { + val value = mDataFactory.getParamIntensity(item.key) + val stand = mModelAttributeRange[item.key]!!.stand + if (DecimalUtils.doubleEquals(value, stand)) { + viewHolder?.setImageResource(R.id.iv_control, item.closeRes) + } else { + viewHolder?.setImageResource(R.id.iv_control, item.openRes) + } + mBeautyAdapter.notifyDataSetChanged() + } + + /** + * 重置还原按钮状态 + */ + private fun setRecoverFaceSkinEnable(enable: Boolean) { + if (enable) { + tv_beauty_recover.alpha = 1f + iv_beauty_recover.alpha = 1f + } else { + tv_beauty_recover.alpha = 0.6f + iv_beauty_recover.alpha = 0.6f + } + lyt_beauty_recover.isEnabled = enable + } + + + /** + * 遍历美肤数据确认还原按钮是否可以点击 + */ + private fun checkFaceSkinChanged(): Boolean { + val item = mSkinBeauty[mSkinIndex] + var value = mDataFactory.getParamIntensity(item.key) + var default = mModelAttributeRange[item.key]!!.default + if (!DecimalUtils.doubleEquals(value, default)) { + return true + } + mSkinBeauty.forEach { + value = mDataFactory.getParamIntensity(it.key) + default = mModelAttributeRange[it.key]!!.default + if (!DecimalUtils.doubleEquals(value, default)) { + return true + } + } + return false + } + + /** + * 遍历美型数据确认还原按钮是否可以点击 + */ + private fun checkFaceShapeChanged(): Boolean { + if (checkFaceShapeChanged(mShapeBeauty) || checkFaceShapeChanged(mShapeBeautySubItem)) + return true + return false + } + + /** + * 遍历美型数据确认还原按钮是否可以点击 + */ + private fun checkFaceShapeChanged(shapeBeauty: ArrayList): Boolean { + var value: Double + var default: Double + if (shapeBeauty.size > mShapeIndex) { + var item = shapeBeauty[mShapeIndex] + item?.let { + value = mDataFactory.getParamIntensity(item.key) + default = mModelAttributeRange[item.key]!!.default + if (!DecimalUtils.doubleEquals(value, default)) { + return true + } + } + } + + shapeBeauty.forEach { + when (it.buttonType) { + FaceBeautyBean.ButtonType.NORMAL_BUTTON -> { + value = mDataFactory.getParamIntensity(it.key) + default = mModelAttributeRange[it.key]!!.default + if (!DecimalUtils.doubleEquals(value, default)) { + return true + } + } + } + } + + return false + } + + + /** + * 还原 美型、美肤数据 + */ + private fun recoverData() { + when (beauty_radio_group.checkedCheckBoxId) { + R.id.beauty_radio_skin_beauty -> { + mSkinBeauty.forEach { + val default = mModelAttributeRange[it.key]!!.default + mDataFactory.updateParamIntensity(it.key, default) + } + val item = mSkinBeauty[mSkinIndex] + val value = mDataFactory.getParamIntensity(item.key) + val stand = mModelAttributeRange[item.key]!!.stand + val maxRange = mModelAttributeRange[item.key]!!.maxRange + seekToSeekBar(value, stand, maxRange) + mBeautyAdapter.notifyDataSetChanged() + setRecoverFaceSkinEnable(false) + } + R.id.beauty_radio_face_shape -> { + //还原主项和子项 + mShapeBeauty.forEach { + when (it.buttonType) { + FaceBeautyBean.ButtonType.NORMAL_BUTTON -> { + val default = mModelAttributeRange[it.key]!!.default + mDataFactory.updateParamIntensity(it.key, default) + } + } + } + + //还原子项 + mShapeBeautySubItem.forEach { + when (it.buttonType) { + FaceBeautyBean.ButtonType.NORMAL_BUTTON -> { + val default = mModelAttributeRange[it.key]!!.default + mDataFactory.updateParamIntensity(it.key, default) + } + } + } + + //获取当前shapeAdapter中被选中的项 + var value = 0.0 + var stand = 0.0 + var maxRange = 1.0 + if (mShapeIndex > 0) { + val item = mBeautyAdapter.getData(mShapeIndex) + when (item.buttonType) { + FaceBeautyBean.ButtonType.NORMAL_BUTTON -> { + value = mDataFactory.getParamIntensity(item.key) + stand = mModelAttributeRange[item.key]!!.stand + maxRange = mModelAttributeRange[item.key]!!.maxRange + } + } + } + seekToSeekBar(value, stand, maxRange) + mBeautyAdapter.notifyDataSetChanged() + setRecoverFaceSkinEnable(false) + } + } + } + + + /** + * 底部动画处理 + * @param isOpen Boolean + */ + private fun changeBottomLayoutAnimator(isOpen: Boolean) { + if (isBottomShow == isOpen) { + return + } + val start = if (isOpen) resources.getDimension(R.dimen.x1).toInt() else resources.getDimension(R.dimen.x268).toInt() + val end = if (isOpen) resources.getDimension(R.dimen.x268).toInt() else resources.getDimension(R.dimen.x1).toInt() + + if (bottomLayoutAnimator != null && bottomLayoutAnimator!!.isRunning) { + bottomLayoutAnimator!!.end() + } + bottomLayoutAnimator = ValueAnimator.ofInt(start, end).setDuration(150) + bottomLayoutAnimator!!.addUpdateListener { animation -> + val height = animation.animatedValue as Int + val params = fyt_bottom_view.layoutParams as LinearLayout.LayoutParams + params.height = height + fyt_bottom_view.layoutParams = params + if (onBottomAnimatorChangeListener != null) { + val showRate = 1.0f * (height - start) / (end - start) + onBottomAnimatorChangeListener?.onBottomAnimatorChangeListener(if (!isOpen) 1 - showRate else showRate) + } + if (DecimalUtils.floatEquals(animation.animatedFraction, 1.0f) && isOpen) { + iv_compare.visibility = View.VISIBLE + } + } + bottomLayoutAnimator!!.start() + isBottomShow = isOpen + } + + override fun onDetachedFromWindow() { + //被销毁前,记录此时的UI值,用于下一次启动的时候恢复 + mSubItemUIValueCache.forEach { + //应该要将UI值保存用于后续恢复 + + } + super.onDetachedFromWindow() + } + + /* item入场动画总开关 */ + val openEnterAnimation = false + + /* 是否需要对该子项进行入场动画 */ + var needEnterAnimation = false + + /** + * recycleView ITEM 子项入场动画 + */ + fun enterAnimation(view:View){ + //动画集合 + val animSet = AnimationSet(false) + //位移动画 + val translateAnim = TranslateAnimation( + Animation.ABSOLUTE, 0f, Animation.ABSOLUTE, 0f, + Animation.ABSOLUTE, 100f, Animation.ABSOLUTE, 0f) + //渐变动画 + val alphaAnim = AlphaAnimation(0.0f, 1.0f) + animSet.addAnimation(translateAnim) + animSet.addAnimation(alphaAnim) + animSet.duration = 300 + animSet.fillAfter = true + animSet.addAnimation(alphaAnim) + view.startAnimation(animSet) + } + + /** + * 是否展示还原按钮 + */ + fun setResetButton(isVisible:Boolean) { + if (isVisible) + iv_reset.visibility = View.VISIBLE + else + iv_reset.visibility = View.GONE + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/control/MakeupControlView.java b/FaceUnity/src/main/java/com/yunbao/faceunity/control/MakeupControlView.java index 8e3ab260e..9bc6e8b80 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/control/MakeupControlView.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/control/MakeupControlView.java @@ -23,7 +23,7 @@ import com.yunbao.faceunity.seekbar.DiscreteSeekBar; import java.util.ArrayList; /** - * DESC: + * DESC:美妆 * Created on 2021/4/26 */ public class MakeupControlView extends BaseControlView { diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/control/PropControlView.java b/FaceUnity/src/main/java/com/yunbao/faceunity/control/PropControlView.java index d5e0307ef..47194834a 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/control/PropControlView.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/control/PropControlView.java @@ -20,7 +20,7 @@ import com.yunbao.faceunity.infe.AbstractPropDataFactory; import java.util.ArrayList; /** - * DESC: + * DESC:贴图、AR面具 * Created on 2021/4/26 */ public class PropControlView extends BaseControlView { diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/AnimojiDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/AnimojiDataFactory.java new file mode 100644 index 000000000..b89e52e13 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/AnimojiDataFactory.java @@ -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; + +/** + * DESC:Animoji业务工厂 + * 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 animojiBeans; + /*Animoji滤镜数据*/ + private ArrayList 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 getAnimojis() { + return animojiBeans; + } + + /** + * 动漫滤镜列表 + * + * @return + */ + @Override + public ArrayList 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); + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/AvatarDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/AvatarDataFactory.java new file mode 100644 index 000000000..2ab36dc79 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/AvatarDataFactory.java @@ -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 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 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; + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/BgSegGreenDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/BgSegGreenDataFactory.java new file mode 100644 index 000000000..ff10231e0 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/BgSegGreenDataFactory.java @@ -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 mBgSegGreenBackgroundBeans; + /* 绿幕抠像当前背景下标 */ + private int mCurrentBackgroundIndex; + + /*绿幕抠像安全区域列表*/ + private ArrayList 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 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 getModelAttributeRange() { + return BgSegGreenSource.buildModelAttributeRange(); + } + + /** + * 获取绿幕抠像功能列表 + * + * @return + */ + @Override + public ArrayList getBgSegGreenActions() { + return BgSegGreenSource.buildBgSegGreenAction(); + } + + /** + * 获取绿幕抠像安全区域功能列表 + * + * @return + */ + @Override + public ArrayList getBgSegGreenSafeAreas() { + return mBgSegGreenSafeAreaBeans; + } + + /** + * 获取绿幕抠像背景列表 + * + * @return + */ + @Override + public ArrayList 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 bgSegGreenSetMapping = new HashMap() { + { + put(BgSegGreenParam.SIMILARITY, value -> getCurrentBgSegGreenModel().setSimilarity(value)); + put(BgSegGreenParam.SMOOTHNESS, value -> getCurrentBgSegGreenModel().setSmoothness(value)); + put(BgSegGreenParam.TRANSPARENCY, value -> getCurrentBgSegGreenModel().setTransparency(value)); + } + }; + + /*模型映射获取模型值*/ + private final HashMap bgSegGreenGetMapping = new HashMap() { + { + 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)); + } + +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyData.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyData.java new file mode 100644 index 000000000..2fe86d58a --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyData.java @@ -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 filterMap = new HashMap<>(); + + /* 滤镜相关 */ + /* 滤镜名称 */ + public String filterName = FaceBeautyFilterEnum.ORIGIN; + /* 滤镜程度 */ + public double filterIntensity = 0.0f; +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyDataFactory.java index a23b83838..5ac58cd6a 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyDataFactory.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceBeautyDataFactory.java @@ -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 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 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 skinBeauty = getSkinBeauty(); + ArrayList shapeBeauty = getShapeBeauty(); + HashMap 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 hashMap) { + CurrentFaceShapeUIValue.currentFaceShapeValue.clear(); + CurrentFaceShapeUIValue.currentFaceShapeValue.putAll(hashMap); + } + + /** + * 获取当前脸型的UI值 + */ + public HashMap 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 faceBeautySetMapping = new HashMap() {{ @@ -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 currentFaceShapeValue = new HashMap<>(); } } diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceUnityDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceUnityDataFactory.java index d807e1baf..df73630a4 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceUnityDataFactory.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/FaceUnityDataFactory.java @@ -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); } /** diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/LightMakeupDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/LightMakeupDataFactory.java new file mode 100644 index 000000000..6e5dce740 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/LightMakeupDataFactory.java @@ -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 lightMakeupBeans; + /* 当前轻美妆选中下标 */ + private int currentLightMakeupIndex; + + + public LightMakeupDataFactory(int index) { + currentLightMakeupIndex = index; + lightMakeupBeans = LightMakeupSource.buildLightMakeup(); + } + + /** + * 获取轻美妆队列 + * + * @return + */ + @Override + public ArrayList 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); + } + } + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/data/PropDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/data/PropDataFactory.java index 6479690f3..0997babef 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/data/PropDataFactory.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/data/PropDataFactory.java @@ -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 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); + } + } } diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimationFilterBean.java b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimationFilterBean.java new file mode 100644 index 000000000..7fd7ddd28 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimationFilterBean.java @@ -0,0 +1,27 @@ +package com.yunbao.faceunity.entity; + +public class AnimationFilterBean { + private int style=0; + private int iconId; + + public AnimationFilterBean(int style, int iconId) { + this.style = style; + this.iconId = iconId; + } + + public int getStyle() { + return style; + } + + public void setStyle(int style) { + this.style = style; + } + + public int getIconId() { + return iconId; + } + + public void setIconId(int iconId) { + this.iconId = iconId; + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimojiBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimojiBean.kt new file mode 100644 index 000000000..c95bff01d --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AnimojiBean.kt @@ -0,0 +1,9 @@ +package com.yunbao.faceunity.entity + +/** + * 道具 + * @property iconId Int 图标 + * @property path String? Animoji 道具路径 + * @constructor + */ +data class AnimojiBean(val iconId: Int, val path: String?) \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AvatarBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AvatarBean.kt new file mode 100644 index 000000000..689675f98 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/AvatarBean.kt @@ -0,0 +1,10 @@ +package com.yunbao.faceunity.entity + + +/** + * + * DESC: + * Created on 2020/12/4 + * + */ +data class AvatarBean(val iconId: Int, val des: String) \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBackgroundBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBackgroundBean.kt new file mode 100644 index 000000000..f7807e753 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBackgroundBean.kt @@ -0,0 +1,11 @@ +package com.yunbao.faceunity.entity + + +/** + * + * DESC: + * Created on 2020/12/4 + * + */ + +data class BgSegGreenBackgroundBean(val desRes: Int, val iconRes: Int, val filePath: String? = null) \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBean.kt new file mode 100644 index 000000000..f2c3654f5 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenBean.kt @@ -0,0 +1,18 @@ +package com.yunbao.faceunity.entity + + +/** + * + * DESC: + * Created on 2020/12/4 + * + */ + +data class BgSegGreenBean(val key: String, val desRes: Int, val closeRes: Int, val openRes: Int, val type: ButtonType) { + enum class ButtonType{ + NORMAL1_BUTTON,//普通一号按钮 + NORMAL2_BUTTON,//普通二号按钮 + BACK_BUTTON,//返回按钮 + SWITCH_BUTTON//切换按钮,切换整个按钮功能 + } +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenSafeAreaBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenSafeAreaBean.kt new file mode 100644 index 000000000..fc5a1f18a --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/BgSegGreenSafeAreaBean.kt @@ -0,0 +1,32 @@ +package com.yunbao.faceunity.entity + + +/** + * + * DESC: + * Created on 2020/12/4 + * + */ + +data class BgSegGreenSafeAreaBean(val iconRes: Int, val type: ButtonType, val filePath: String? = null,val isAssetFile: Boolean = true) { + + constructor(iconRes: Int, type: ButtonType) : this( + iconRes, + type, + null, + true + ) + + constructor(iconRes: Int, type: ButtonType, filePath :String) : this( + iconRes, + type, + filePath, + true + ) + enum class ButtonType{ + NORMAL1_BUTTON,//普通一号按钮,普通安全区域按钮 + NORMAL2_BUTTON,//普通二号按钮,用于自定义按钮 + BACK_BUTTON,//返回按钮 + NONE_BUTTON,//不选择按钮 + } +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.java b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.java deleted file mode 100644 index bb0aebb1f..000000000 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.java +++ /dev/null @@ -1,70 +0,0 @@ -package com.yunbao.faceunity.entity; - -/** - * DESC:美颜 - * Created on 2021/4/26 - */ -public class FaceBeautyBean { - - private String key;//名称标识 - private int desRes;//描述 - private int closeRes;//图片 - private int openRes;//图片 - private int toastDesRes; - private boolean canUseFunction; - private ButtonType buttonType=ButtonType.NORMAL_BUTTON; - - public FaceBeautyBean(String key, int desRes, int closeRes, int openRes) { - this.key = key; - this.desRes = desRes; - this.closeRes = closeRes; - this.openRes = openRes; - } - - public FaceBeautyBean(String key, int desRes, int closeRes, int openRes, int toastDesRes, boolean canUseFunction) { - this.key = key; - this.desRes = desRes; - this.closeRes = closeRes; - this.openRes = openRes; - this.toastDesRes = toastDesRes; - this.canUseFunction = canUseFunction; - this.buttonType = buttonType; - } - - public String getKey() { - return key; - } - - public void setKey(String key) { - this.key = key; - } - - public int getDesRes() { - return desRes; - } - - public void setDesRes(int desRes) { - this.desRes = desRes; - } - - public int getCloseRes() { - return closeRes; - } - - public void setCloseRes(int closeRes) { - this.closeRes = closeRes; - } - - public int getOpenRes() { - return openRes; - } - - public void setOpenRes(int openRes) { - this.openRes = openRes; - } - enum ButtonType{ - NORMAL_BUTTON, - BACK_BUTTON, - SUB_ITEM_BUTTON - } -} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.kt new file mode 100644 index 000000000..34b3f901e --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyBean.kt @@ -0,0 +1,47 @@ +package com.yunbao.faceunity.entity + + +/** + * + * @property key String 名称标识 + * @property desRes Int 描述 + * @property closeRes Int 图片 + * @property openRes Int 图片 + * @property buttonType 按钮类型 + * @constructor + */ +data class FaceBeautyBean( + val key: String, + val desRes: Int, + val closeRes: Int, + val openRes: Int, + val toastDesRes: Int, + val canUseFunction:Boolean = true, + val buttonType: ButtonType = ButtonType.NORMAL_BUTTON//定义一项按钮功能 普通按钮 返回按钮 子项按钮 +) { + constructor(key: String, desRes: Int, closeRes: Int, openRes: Int) : this( + key, + desRes, + closeRes, + openRes, + 0, + true, + ButtonType.NORMAL_BUTTON + ) + + constructor(key: String, desRes: Int, closeRes: Int, openRes: Int,toastDesRes: Int,canUseFunction: Boolean) : this( + key, + desRes, + closeRes, + openRes, + toastDesRes, + canUseFunction, + ButtonType.NORMAL_BUTTON + ) + + enum class ButtonType{ + NORMAL_BUTTON, + BACK_BUTTON, + SUB_ITEM_BUTTON + } +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyStyleBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyStyleBean.kt new file mode 100644 index 000000000..2bba7b05f --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FaceBeautyStyleBean.kt @@ -0,0 +1,10 @@ +package com.yunbao.faceunity.entity + +/** + * 滤镜 + * @property key String 名称标识 + * @property imageRes Int 图片 + * @property desRes Int 描述 + * @constructor + */ +data class FaceBeautyStyleBean @JvmOverloads constructor(val key: String, val imageRes: Int, val desRes: Int) \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FunctionEnum.java b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FunctionEnum.java new file mode 100644 index 000000000..b1b609ebc --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/FunctionEnum.java @@ -0,0 +1,25 @@ +package com.yunbao.faceunity.entity; + +public class FunctionEnum { + public final static int FACE_BEAUTY = 1; + public final static int MAKE_UP = 2; + public final static int STICKER = 3; + public final static int ANIMOJI = 4; + public final static int HAIR_BEAUTY = 5; + public final static int LIGHT_MAKEUP = 6; + public final static int AR_MASK = 7; + public final static int BIG_HEAD = 8; + public final static int POSTER_CHANGE = 9; + public final static int EXPRESSION_RECOGNITION = 10; + public final static int MUSIC_FILTER = 11; + public final static int FACE_WARP = 12; + public final static int BODY_BEAUTY = 13; + public final static int AVATAR = 14; + public final static int ACTION_RECOGNITION = 15; + public final static int PORTRAIT_SEGMENT = 16; + public final static int GESTURE_RECOGNITION = 17; + public final static int BG_SEG_GREEN = 18; + public final static int HUMAN_OUTLINE = 19; + public final static int BG_SEG_CUSTOM = 20; + public final static int FINE_STICKER = 21; +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/LightMakeupBean.java b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/LightMakeupBean.java new file mode 100644 index 000000000..96f0561ec --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/LightMakeupBean.java @@ -0,0 +1,67 @@ +package com.yunbao.faceunity.entity; + +public class LightMakeupBean { + int nameRes; + int iconRes; + String key; + double intensity; + String filterName; + double filterIntensity; + + public LightMakeupBean(int nameRes, int iconRes, String key, double intensity, String filterName, double filterIntensity) { + this.nameRes = nameRes; + this.iconRes = iconRes; + this.key = key; + this.intensity = intensity; + this.filterName = filterName; + this.filterIntensity = filterIntensity; + } + + public int getNameRes() { + return nameRes; + } + + public void setNameRes(int nameRes) { + this.nameRes = nameRes; + } + + public int getIconRes() { + return iconRes; + } + + public void setIconRes(int iconRes) { + this.iconRes = iconRes; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public double getIntensity() { + return intensity; + } + + public void setIntensity(double intensity) { + this.intensity = intensity; + } + + public String getFilterName() { + return filterName; + } + + public void setFilterName(String filterName) { + this.filterName = filterName; + } + + public double getFilterIntensity() { + return filterIntensity; + } + + public void setFilterIntensity(double filterIntensity) { + this.filterIntensity = filterIntensity; + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.java b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.java deleted file mode 100644 index ad8e2d811..000000000 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.yunbao.faceunity.entity; - -/** - * 模型单项补充模型 - */ -public class ModelAttributeData { - private double defaultV = 0.0;//默认值 - private double standV = 0.0;//无变化时候的基准值 - private double minRange = 0.0;//范围最小值 - private double maxRange = 1.0;//范围最大值 - - public ModelAttributeData(double defaultV, double standV, double minRange, double maxRange) { - this.defaultV = defaultV; - this.standV = standV; - this.minRange = minRange; - this.maxRange = maxRange; - } - - - public double getDefaultV() { - return defaultV; - } - - public void setDefaultV(double defaultV) { - this.defaultV = defaultV; - } - - public double getStandV() { - return standV; - } - - public void setStandV(double standV) { - this.standV = standV; - } - - public double getMinRange() { - return minRange; - } - - public void setMinRange(double minRange) { - this.minRange = minRange; - } - - public double getMaxRange() { - return maxRange; - } - - public void setMaxRange(double maxRange) { - this.maxRange = maxRange; - } -} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.kt new file mode 100644 index 000000000..7bbd2e3c9 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/ModelAttributeData.kt @@ -0,0 +1,12 @@ +package com.yunbao.faceunity.entity + + +/** + * 模型单项补充模型 + * @property default Double 默认值 + * @property stand Double 无变化时候的基准值 + * @property minRange Double 范围最小值 + * @property maxRange Double 范围最大值 + * @constructor + */ +data class ModelAttributeData(val default: Double=0.0, val stand: Double = 0.0, val minRange: Double = 0.0, val maxRange: Double = 1.0) \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.java b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.java deleted file mode 100644 index 12b45abd7..000000000 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.java +++ /dev/null @@ -1,32 +0,0 @@ -package com.yunbao.faceunity.entity; - -/** - * DESC:道具 - * Created on 2021/4/26 - */ -public class PropBean { - private int iconId; - private String path; - - - public PropBean(int iconId, String path) { - this.iconId = iconId; - this.path = path; - } - - public int getIconId() { - return iconId; - } - - public void setIconId(int iconId) { - this.iconId = iconId; - } - - public String getPath() { - return path; - } - - public void setPath(String path) { - this.path = path; - } -} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.kt new file mode 100644 index 000000000..dcb2ebf16 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropBean.kt @@ -0,0 +1,14 @@ +package com.yunbao.faceunity.entity + +/** + * 道具 + * @property iconId Int 图标 + * @property path String 道具路径 + * @property descId Int 道具提示 + * @constructor + */ +data class PropBean @JvmOverloads constructor( + val iconId: Int, + val path: String?, + val descId: Int = 0 +) \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropCustomBean.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropCustomBean.kt new file mode 100644 index 000000000..3f35a8800 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/entity/PropCustomBean.kt @@ -0,0 +1,18 @@ +package com.yunbao.faceunity.entity + +/** + * 道具 + * @property iconId Int 图标 + * @property path String 道具路径 + * @property descId Int 道具提示 + * @property descId Int 类型 -2 为添加事件 -1为空 其他多道具类型 + * @property iconPath 图标路径 + * @constructor + */ +data class PropCustomBean @JvmOverloads constructor( + val iconId: Int, + val path: String?, + val type: Int = -1, + val descId: Int = 0, + val iconPath: String? = null +) \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAnimojiDataFactory.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAnimojiDataFactory.kt new file mode 100644 index 000000000..3aa8a98f0 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAnimojiDataFactory.kt @@ -0,0 +1,31 @@ +package com.yunbao.faceunity.infe + +import com.yunbao.faceunity.entity.AnimationFilterBean +import com.yunbao.faceunity.entity.AnimojiBean + + +/** + * + * DESC: + * Created on 2020/12/24 + * + */ +abstract class AbstractAnimojiDataFactory { + + /* 当前选中动漫贴图下标 */ + abstract var currentAnimojiIndex: Int + + /* 动漫贴图队列 */ + abstract val animojis: ArrayList + + /* 当前选中滤镜下标 */ + abstract var currentFilterIndex: Int + + /* 滤镜队列 */ + abstract val filters: ArrayList + + abstract fun onAnimojiSelected(data: AnimojiBean) + + abstract fun onFilterSelected(data: AnimationFilterBean) + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAvatarDataFactory.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAvatarDataFactory.kt new file mode 100644 index 000000000..9f4211f80 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractAvatarDataFactory.kt @@ -0,0 +1,35 @@ +package com.yunbao.faceunity.infe + +import com.yunbao.faceunity.entity.AvatarBean + + +/** + * + * DESC: + * Created on 2021/1/6 + * + */ +abstract class AbstractAvatarDataFactory { + + /** + * 人物队列 + */ + abstract val members: ArrayList + + /** + * 默认选中人物下标 + */ + abstract var currentMemberIndex: Int + + /** + * true 全身、 false 半身 驱动切换 + */ + abstract var isHumanTrackSceneFull: Boolean + + /** + * 当前人物选中 + * @param bean AvatarBean + */ + abstract fun onMemberSelected(bean:AvatarBean) + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractBgSegGreenDataFactory.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractBgSegGreenDataFactory.kt new file mode 100644 index 000000000..e4c07e605 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractBgSegGreenDataFactory.kt @@ -0,0 +1,97 @@ +package com.yunbao.faceunity.infe + + +import com.yunbao.faceunity.entity.BgSegGreenBackgroundBean +import com.yunbao.faceunity.entity.BgSegGreenBean +import com.yunbao.faceunity.entity.BgSegGreenSafeAreaBean +import com.yunbao.faceunity.entity.ModelAttributeData + + +/** + * + * DESC: + * Created on 2020/12/29 + * + */ +abstract class AbstractBgSegGreenDataFactory { + + /* 绿幕抠像项目数据扩展模型 */ + abstract val modelAttributeRange: HashMap + + /* 绿幕抠像功能列表 */ + abstract val bgSegGreenActions: ArrayList + + /* 绿幕抠图安全区域功能列表*/ + abstract val bgSegGreenSafeAreas: ArrayList + + /* 安全区域下标 */ + abstract var bgSafeAreaIndex: Int + + /* 刷新安全区域UI */ + abstract fun updateSafeAreaBeansAndIndex() :Boolean + + /* 绿幕抠像背景列表 */ + abstract val bgSegGreenBackgrounds: ArrayList + + /* 绿幕抠像当前背景下标 */ + abstract var backgroundIndex: Int + + + /** + * 背景图片变更 + * @param data BgSegGreenBackgroundBean + */ + abstract fun onBackgroundSelected(data: BgSegGreenBackgroundBean) + + /** + * 自定义安全区域 + */ + abstract fun onSafeAreaAdd() + + /** + * 安全区域变更 + * @param data BgSegGreenSafeAreaBean + */ + abstract fun onSafeAreaSelected(data: BgSegGreenSafeAreaBean?) + + /** + * 是否开启安全区域总开关 + */ + abstract fun isUseTemplate():Boolean + + /** + * 取色锚点颜色变更 + * @param array DoubleArray + */ + abstract fun onColorRGBChanged(array: DoubleArray) + + /** + * 绿幕开关 + * @param enable Boolean + */ + abstract fun onBgSegGreenEnableChanged(enable: Boolean) + + + /** + * 根据名称标识获取对应的值 + * @param key String 标识 + * @return Double 值 + */ + abstract fun getParamIntensity(key: String): Double + + /** + * 根据名称标识更新对应的值 + * @param key String 标识 + * @return Double 值 + */ + abstract fun updateParamIntensity(key: String, value: Double) + + /** + * 是否调用取色器功能 + * + * @param selected + * @param color + */ + abstract fun onColorPickerStateChanged(selected: Boolean, color: Int) + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.java deleted file mode 100644 index 0c2f5ccc2..000000000 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.java +++ /dev/null @@ -1,103 +0,0 @@ -package com.yunbao.faceunity.infe; - - -import com.yunbao.faceunity.entity.FaceBeautyBean; -import com.yunbao.faceunity.entity.FaceBeautyFilterBean; -import com.yunbao.faceunity.entity.ModelAttributeData; - -import java.util.ArrayList; -import java.util.HashMap; - -/** - * DESC:数据构造工厂抽象类 - * Created on 2021/4/26 - */ -public abstract class AbstractFaceBeautyDataFactory { - - - /** - * 美肤底部菜单数据 - * - * @return - */ - public abstract ArrayList getSkinBeauty(); - - - /** - * 美型底部菜单数据 - * - * @return - */ - public abstract ArrayList getShapeBeauty(); - - - /** - * 滤镜底部菜单数据 - * - * @return - */ - public abstract ArrayList getBeautyFilters(); - - /** - * 获取当前滤镜下标 - * - * @return - */ - public abstract int getCurrentFilterIndex(); - - /** - * 设置当前滤镜下标 - * - * @param currentFilterIndex - */ - public abstract void setCurrentFilterIndex(int currentFilterIndex); - - - /** - * 美颜项目数据扩展模型 - * - * @return - */ - public abstract HashMap getModelAttributeRange(); - - /** - * 切换滤镜 - * - * @param name String - * @param intensity Double - */ - public abstract void onFilterSelected(String name, double intensity, int resDes); - - - /** - * 更改滤镜强度 - * - * @param intensity Double - */ - public abstract void updateFilterIntensity(double intensity); - - /** - * 美颜开关 - * - * @param enable Boolean - */ - public abstract void enableFaceBeauty(boolean enable); - - /** - * 获取单项强度 - * - * @param key String - * @return Double - */ - public abstract double getParamIntensity(String key); - - /** - * 设置单项强度 - * - * @param key String - * @param value Double - */ - public abstract void updateParamIntensity(String key, double value); - - -} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.kt new file mode 100644 index 000000000..166018fac --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractFaceBeautyDataFactory.kt @@ -0,0 +1,105 @@ +package com.yunbao.faceunity.infe + + +import com.yunbao.faceunity.entity.FaceBeautyBean +import com.yunbao.faceunity.entity.FaceBeautyFilterBean +import com.yunbao.faceunity.entity.FaceBeautyStyleBean +import com.yunbao.faceunity.entity.ModelAttributeData + + +/** + * + * DESC:数据构造工厂接口类 + * Created on 2020/12/23 + * + */ +abstract class AbstractFaceBeautyDataFactory { + + /*美肤底部菜单数据*/ + abstract val skinBeauty: ArrayList + + /*美型底部菜单数据*/ + abstract val shapeBeauty: ArrayList + + /*美型脸型子项数据*/ + abstract val shapeBeautySubItem: ArrayList + + /* 滤镜底部菜单数据*/ + abstract val beautyFilters: ArrayList + + /* 风格底部菜单数据*/ + abstract val beautyStyles: ArrayList + + /*系统推荐配置滤镜对应下标*/ + abstract var currentFilterIndex: Int + + /* 美颜项目数据扩展模型 */ + abstract val modelAttributeRange: HashMap + + /*系统风格对应下标*/ + abstract var currentStyleIndex: Int + + /** + * 切换滤镜 + * @param name String + * @param intensity Double + */ + abstract fun onFilterSelected(name: String, intensity: Double, resDes: Int) + + /** + * 切换风格 + * @param name String + */ + abstract fun onStyleSelected(name: String?) + + /** + * 更改滤镜强度 + * @param intensity Double + */ + abstract fun updateFilterIntensity(intensity: Double) + + /** + * 美颜开关 + * @param enable Boolean + */ + abstract fun enableFaceBeauty(enable: Boolean) + + /** + * 获取单项强度 + * @param key String + * @return Double + */ + abstract fun getParamIntensity(key: String): Double + + /** + * 获取one hot的脸型 + */ + abstract fun getCurrentOneHotFaceShape(): String + + /** + * 设置当前one hot的脸型 + */ + abstract fun setCurrentOneHotFaceShape(faceShape:String) + + /** + * 设置当前脸型的UI值 + */ + abstract fun setCurrentFaceShapeUIValue(hashMap:HashMap) + + /** + * 获取当前脸型的UI值 + */ + abstract fun getCurrentFaceShapeUIValue() :HashMap + + /** + * 设置单项强度 + * @param key String + * @param value Double + */ + abstract fun updateParamIntensity(key: String, value: Double) + + /** + * 将所有效果置空 -> 变成标准值 + */ + abstract fun resetParamIntensity() +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractLightMakeupDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractLightMakeupDataFactory.java new file mode 100644 index 000000000..99ea19923 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractLightMakeupDataFactory.java @@ -0,0 +1,28 @@ +package com.yunbao.faceunity.infe; + +import com.yunbao.faceunity.entity.LightMakeupBean; + +import java.util.ArrayList; + +public abstract class AbstractLightMakeupDataFactory { + private int currentLightMakeupIndex; + private ArrayList lightMakeUpBeans; + public abstract void onLightMakeupSelected(LightMakeupBean data); + public abstract void onLightMakeupIntensityChanged(double intensity); + + public int getCurrentLightMakeupIndex() { + return currentLightMakeupIndex; + } + + public void setCurrentLightMakeupIndex(int currentLightMakeupIndex) { + this.currentLightMakeupIndex = currentLightMakeupIndex; + } + + public ArrayList getLightMakeUpBeans() { + return lightMakeUpBeans; + } + + public void setLightMakeUpBeans(ArrayList lightMakeUpBeans) { + this.lightMakeUpBeans = lightMakeUpBeans; + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropCustomDataFactory.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropCustomDataFactory.kt new file mode 100644 index 000000000..571ed324f --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropCustomDataFactory.kt @@ -0,0 +1,45 @@ +package com.yunbao.faceunity.infe + +import com.yunbao.faceunity.entity.PropCustomBean + + +/** + * + * DESC:贴图道具 + * Created on 2020/12/23 + * + */ +abstract class AbstractPropCustomDataFactory { + + /** + * 默认选中道具下标 + */ + abstract var currentPropIndex: Int + + + /** + * 道具队列 + */ + abstract val propCustomBeans: ArrayList + + + /** + * 道具选中 + * @param bean StickerBean + */ + abstract fun onItemSelected(bean: PropCustomBean) + + + /** + * 道具选中 + */ + abstract fun onAddPropCustomBeanClick() + + + companion object { + const val TYPE_NONE = -1 + const val TYPE_ADD = -99 + } + + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.java b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.java deleted file mode 100644 index 743dde995..000000000 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.java +++ /dev/null @@ -1,42 +0,0 @@ -package com.yunbao.faceunity.infe; - -import com.yunbao.faceunity.entity.PropBean; - -import java.util.ArrayList; - -/** - * DESC:数据构造工厂抽象类 - * Created on 2021/4/26 - */ -public abstract class AbstractPropDataFactory { - - - /** - * 获取当前选中下标 - * - * @return - */ - public abstract int getCurrentPropIndex(); - - /** - * 设置当前选中下标 - * - * @param currentPropIndex - */ - public abstract void setCurrentPropIndex(int currentPropIndex); - - /** - * 获取道具队列 - * - * @return - */ - public abstract ArrayList getPropBeans(); - - /** - * 道具选中 - * - * @param bean StickerBean - */ - public abstract void onItemSelected(PropBean bean); - -} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.kt b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.kt new file mode 100644 index 000000000..e81be3240 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/infe/AbstractPropDataFactory.kt @@ -0,0 +1,33 @@ +package com.yunbao.faceunity.infe + +import com.yunbao.faceunity.entity.PropBean + + +/** + * + * DESC:贴图道具 + * Created on 2020/12/23 + * + */ +abstract class AbstractPropDataFactory { + + /** + * 默认选中道具下标 + */ + abstract var currentPropIndex: Int + + + /** + * 道具队列 + */ + abstract val propBeans: ArrayList + + + /** + * 道具选中 + * @param bean StickerBean + */ + abstract fun onItemSelected(bean: PropBean) + + +} \ No newline at end of file diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/AnimojiSource.java b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/AnimojiSource.java new file mode 100644 index 000000000..5cce78374 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/AnimojiSource.java @@ -0,0 +1,59 @@ +package com.yunbao.faceunity.repo; + +import com.faceunity.core.model.animationFilter.AnimationFilterTypeEnum; +import com.yunbao.faceunity.R; +import com.yunbao.faceunity.entity.AnimationFilterBean; +import com.yunbao.faceunity.entity.AnimojiBean; + +import java.util.ArrayList; + +/** + * DESC:Animoji数据构造 + * Created on 2021/3/25 + */ +public class AnimojiSource { + + + /** + * 构造贴图数据 + * + * @return + */ + public static ArrayList buildAnimojis() { + ArrayList array = new ArrayList<>(); + array.add(new AnimojiBean(R.mipmap.icon_control_delete_all, null)); + array.add(new AnimojiBean(R.mipmap.icon_animoji_cartoon_princess, "animoji/cartoon_princess_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_qgirl, "animoji/qgirl_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_kaola, "animoji/kaola_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_wuxia, "animoji/wuxia_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_baihu, "animoji/baihu_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_frog_st, "animoji/frog_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_huangya, "animoji/huangya_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_hetun, "animoji/hetun_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_douniuquan, "animoji/douniuquan_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_hashiqi, "animoji/hashiqi_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_baimao, "animoji/baimao_Animoji.bundle")); + array.add(new AnimojiBean(R.mipmap.icon_animoji_kuloutou, "animoji/kuloutou_Animoji.bundle")); + return array; + } + + /** + * 构造滤镜数据 + * + * @return + */ + public static ArrayList buildFilters() { + ArrayList filters = new ArrayList<>(); + filters.add(new AnimationFilterBean(R.mipmap.icon_control_delete_all, AnimationFilterTypeEnum.Origin)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_anime, AnimationFilterTypeEnum.Comic)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_portrait_dynamiceffect, AnimationFilterTypeEnum.Portrait)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_sketch, AnimationFilterTypeEnum.Sketch)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_oilpainting, AnimationFilterTypeEnum.Oil)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_sandlpainting, AnimationFilterTypeEnum.Sand)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_penpainting, AnimationFilterTypeEnum.Pen)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_pencilpainting, AnimationFilterTypeEnum.Pencil)); + filters.add(new AnimationFilterBean(R.mipmap.icon_cartoon_graffiti, AnimationFilterTypeEnum.Granffiti)); + return filters; + } + +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/AvatarSource.java b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/AvatarSource.java new file mode 100644 index 000000000..1b10d3e0a --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/AvatarSource.java @@ -0,0 +1,160 @@ +package com.yunbao.faceunity.repo; + +import com.faceunity.core.avatar.avatar.Color; +import com.faceunity.core.avatar.avatar.TransForm; +import com.faceunity.core.avatar.model.Avatar; +import com.faceunity.core.avatar.model.Scene; +import com.faceunity.core.entity.FUAnimationData; +import com.faceunity.core.entity.FUAvatarAnimFilterParams; +import com.faceunity.core.entity.FUBundleData; +import com.faceunity.core.entity.FUColorRGBData; +import com.faceunity.core.entity.FUCoordinate3DData; +import com.faceunity.core.entity.FUTranslationScale; +import com.faceunity.core.entity.FUVisibleBundleData; +import com.yunbao.faceunity.R; +import com.yunbao.faceunity.entity.AvatarBean; + +import java.io.File; +import java.util.ArrayList; + +/** + * DESC:Avatar数据构造 + * Created on 2021/3/30 + */ +public class AvatarSource { + // Avatar + private static String BUNDLE_AVATAR_CONTROLLER = "graphics" + File.separator + "controller_cpp.bundle"; + private static String BUNDLE_AVATAR_CONFIG = "pta" + File.separator + "controller_config.bundle"; + private static String BUNDLE_AVATAR_BACKGROUND = "pta" + File.separator + "default_bg.bundle"; + + public static String BOY = "boy"; + public static String GIRL = "girl"; + + /** + * 构造成员列表 + * + * @return + */ + public static ArrayList buildMembers() { + ArrayList avatarBeans = new ArrayList<>(); + avatarBeans.add(new AvatarBean(R.mipmap.icon_avatar_female, GIRL)); + avatarBeans.add(new AvatarBean(R.mipmap.icon_avatar_male, BOY)); + return avatarBeans; + } + + /** + * 构造场景 + * + * @param avatar + * @return + */ + public static Scene buildSceneModel(Avatar avatar) { + FUBundleData controlBundle = new FUBundleData(BUNDLE_AVATAR_CONTROLLER); + FUBundleData avatarConfig = new FUBundleData(BUNDLE_AVATAR_CONFIG); + Scene sceneModel = new Scene(controlBundle, avatarConfig); + sceneModel.addAvatar(avatar); + sceneModel.processorConfig.setEnableHumanProcessor(true); + return sceneModel; + } + + /** + * 获取男孩对象 + * + * @return + */ + public static Avatar buildBoyData(boolean isFull) { + String ptaBoyDir = "pta/boy/"; + ArrayList components = new ArrayList(); + components.add(new FUBundleData(ptaBoyDir + "head.bundle")); + components.add(new FUBundleData(ptaBoyDir + "midBody_male.bundle")); + components.add(new FUBundleData(ptaBoyDir + "male_hair_5.bundle")); + components.add(new FUBundleData(ptaBoyDir + "toushi_7.bundle")); + components.add(new FUBundleData(ptaBoyDir + "peishi_erding_2.bundle")); + components.add(new FUBundleData(ptaBoyDir + "waitao_3.bundle")); + components.add(new FUBundleData(ptaBoyDir + "kuzi_changku_5.bundle")); + components.add(new FUBundleData(ptaBoyDir + "xiezi_tuoxie_2.bundle")); + int[] invisibleList = {2,3,4}; + components.add(new FUVisibleBundleData("",invisibleList,"")); + ArrayList animations = buildAnimations(); + Avatar model = new Avatar(components); + for (FUAnimationData animationData:animations){ + model.animation.addAnimation(animationData); + } + model.color.setColor(Color.Skin,new FUColorRGBData(227.0,158.0,132.0)); + TransForm avatarTransForm = model.transForm; + avatarTransForm.setInstanceEnableHumanAnimDriver(true); + avatarTransForm.setPosition(isFull ? new FUCoordinate3DData(0.0, 58.14, -618.94) : new FUCoordinate3DData(0.0, 11.76, -183.89)); + return model; + } + + /** + * 获取女孩对象 + * + * @return + */ + public static Avatar buildGirlData(boolean isFull) { + String ptaGirlDir = "pta/girl/"; + ArrayList components = new ArrayList(); + components.add(new FUBundleData(ptaGirlDir + "head.bundle")); + components.add(new FUBundleData(ptaGirlDir + "midBody_female.bundle")); + components.add(new FUBundleData(ptaGirlDir + "female_hair_23.bundle")); + components.add(new FUBundleData(ptaGirlDir + "toushi_5.bundle")); + components.add(new FUBundleData(ptaGirlDir + "taozhuang_12.bundle")); + components.add(new FUBundleData(ptaGirlDir + "facemakeup_3.bundle")); + components.add(new FUBundleData(ptaGirlDir + "xiezi_danxie.bundle")); + int[] invisibleList = {2,3,4}; + components.add(new FUVisibleBundleData("",invisibleList,"")); + ArrayList animations = buildAnimations(); + Avatar model = new Avatar(components ); + for (FUAnimationData animationData:animations){ + model.animation.addAnimation(animationData); + } + model.color.setColor(Color.Skin,new FUColorRGBData(255.0,202.0,186.0)); + TransForm avatarTransForm = model.transForm; + avatarTransForm.setInstanceEnableHumanAnimDriver(true); + avatarTransForm.setPosition(isFull ? new FUCoordinate3DData(0.0, 58.14, -618.94) : new FUCoordinate3DData(0.0, 11.76, -183.89)); + return model; + } + + /** + * 外部传入组件和动画构建 + * + * @param strComponents 组件bundle + * @param strAnimations 动画bundle + * @return + */ + public static Avatar buildAvatarData(ArrayList strComponents, ArrayList strAnimations) { + ArrayList components = new ArrayList(); + for (String component : strComponents) { + components.add(new FUBundleData(component)); + } + + Avatar model = new Avatar(components); + for (String animation : strAnimations) { + model.animation.addAnimation(new FUAnimationData(new FUBundleData(animation))); + } + //位置等avatar基本参数构建 + TransForm avatarTransForm = model.transForm; + avatarTransForm.setPosition(new FUCoordinate3DData(20, 45, -618.94)); + avatarTransForm.setTranslationScale(new FUTranslationScale(0.0f,0.0f,0.0f)); + avatarTransForm.setInstanceEnableHumanAnimDriver(true); + model.animation.setHumanProcessorSetAvatarAnimFilterParams(new FUAvatarAnimFilterParams(8, 0.09f, 0.120f)); + return model; + } + + /** + * 构造动画参数 + * + * @return + */ + public static ArrayList buildAnimations() { + String animDir = "pta/gesture/"; + ArrayList animations = new ArrayList(); + animations.add(new FUAnimationData(new FUBundleData(animDir + "anim_idle.bundle"))); + return animations; + } + + public static void setSceneBackGround(Scene sceneModel, boolean hasBackGround) { + sceneModel.setBackgroundBundle(hasBackGround ? new FUBundleData(BUNDLE_AVATAR_BACKGROUND) : null); + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/BgSegGreenSource.java b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/BgSegGreenSource.java new file mode 100644 index 000000000..0ec4f2c6f --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/BgSegGreenSource.java @@ -0,0 +1,145 @@ +package com.yunbao.faceunity.repo; + +import static android.content.Context.MODE_PRIVATE; + +import android.content.SharedPreferences; + + +import com.faceunity.core.controller.bgSegGreen.BgSegGreenParam; +import com.faceunity.core.entity.FUBundleData; +import com.faceunity.core.model.bgSegGreen.BgSegGreen; +import com.yunbao.faceunity.R; +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.utils.FaceUnityConfig; +import com.yunbao.faceunity.utils.FaceUnityData; + +import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * DESC:绿幕抠像数据构造 + * Created on 2021/3/25 + */ +public class BgSegGreenSource { + private static final String GREEN_SAFE_AREA_CUSTOM = "green_safe_area_custom"; + + private static double SIMILARITY = 0.5;//相似度 + private static double SMOOTHNESS = 0.3;//平滑度 + private static double TRANSPARENCY = 0.67;//透明度 + + /** + * 构造绿幕抠像对象 + * + * @return + */ + public static BgSegGreen buildBgSegGreen() { + BgSegGreen bgSegGreen = new BgSegGreen(new FUBundleData(FaceUnityConfig.BUNDLE_BG_SEG_GREEN)); + bgSegGreen.setSimilarity(BgSegGreenSource.SIMILARITY); + bgSegGreen.setSmoothness(BgSegGreenSource.SMOOTHNESS); + bgSegGreen.setTransparency(BgSegGreenSource.TRANSPARENCY); + return bgSegGreen; + } + + /** + * 获取模型属性扩展数据 + * + * @return HashMap + */ + public static HashMap buildModelAttributeRange() { + HashMap params = new HashMap(); + params.put(BgSegGreenParam.SIMILARITY, new ModelAttributeData(SIMILARITY, 0.0, 0.0, 1.0)); + params.put(BgSegGreenParam.SMOOTHNESS, new ModelAttributeData(SMOOTHNESS, 0.0, 0.0, 1.0)); + params.put(BgSegGreenParam.TRANSPARENCY, new ModelAttributeData(TRANSPARENCY, 0.0, 0.0, 1.0)); + return params; + } + + /** + * 绿幕抠像功能列表 + * + * @return + */ + public static ArrayList buildBgSegGreenAction() { + ArrayList actions = new ArrayList(); + actions.add(new BgSegGreenBean(BgSegGreenParam.RGB_COLOR, R.string.bg_seg_green_key_color, R.drawable.icon_green_color_selector, R.drawable.icon_green_color_selector, BgSegGreenBean.ButtonType.NORMAL2_BUTTON)); + actions.add(new BgSegGreenBean(BgSegGreenParam.SIMILARITY, R.string.bg_seg_green_similarity, R.drawable.icon_green_similarityr_close_selector, R.drawable.icon_green_similarityr_open_selector, BgSegGreenBean.ButtonType.NORMAL1_BUTTON)); + actions.add(new BgSegGreenBean(BgSegGreenParam.SMOOTHNESS, R.string.bg_seg_green_smooth, R.drawable.icon_green_smooth_close_selector, R.drawable.icon_green_similarityr_open_selector, BgSegGreenBean.ButtonType.NORMAL1_BUTTON)); + actions.add(new BgSegGreenBean(BgSegGreenParam.TRANSPARENCY, R.string.bg_seg_green_alpha, R.drawable.icon_green_transparency_close_selector, R.drawable.icon_green_transparency_open_selector, BgSegGreenBean.ButtonType.NORMAL1_BUTTON)); + actions.add(new BgSegGreenBean("", R.string.bg_seg_green_safe_area, R.drawable.icon_green_safe_area_close_selector, R.drawable.icon_green_safe_area_open_selector, BgSegGreenBean.ButtonType.SWITCH_BUTTON)); + return actions; + } + + /** + * 绿幕抠像安全区域功能列表 + * + * @return + */ + public static ArrayList buildBgSegGreenSafeArea() { + String fileDir = "bg_seg_green" + File.separator + "sample" + File.separator; + ArrayList safeAreaBeans = new ArrayList(); + safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_control_return, BgSegGreenSafeAreaBean.ButtonType.BACK_BUTTON));//返回 + safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_control_none, BgSegGreenSafeAreaBean.ButtonType.NONE_BUTTON));//不选 + safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_control_square_add, BgSegGreenSafeAreaBean.ButtonType.NORMAL2_BUTTON));//自定义 + BgSegGreenSafeAreaBean customerBean = buildSafeAreaCustomBean(getCachePortraitSegment()); + if (customerBean != null) { + safeAreaBeans.add(customerBean); + } + safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_green_safe_area1, BgSegGreenSafeAreaBean.ButtonType.NORMAL1_BUTTON,fileDir + "safe_area1.jpg"));//区域一 + safeAreaBeans.add(new BgSegGreenSafeAreaBean(R.mipmap.icon_green_safe_area2, BgSegGreenSafeAreaBean.ButtonType.NORMAL1_BUTTON,fileDir + "safe_area2.jpg"));//区域二 + return safeAreaBeans; + } + + /** + * 构造自定义安全区域图片 + * + * @param path + * @return + */ + public static BgSegGreenSafeAreaBean buildSafeAreaCustomBean(String path) { + if (path != null && path.trim().length() > 0 && new File(path).exists()) { + saveCachePortraitSegment(path); + return new BgSegGreenSafeAreaBean(0, BgSegGreenSafeAreaBean.ButtonType.NORMAL1_BUTTON, path,false); + } + return null; + } + + /** + * 绿幕抠像背景列表 + * + * @return + */ + public static ArrayList buildBgSegGreenBackground() { + ArrayList backgroundBeans = new ArrayList<>(); + String fileDir = "bg_seg_green" + File.separator + "sample" + File.separator; + backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.cancel, R.mipmap.icon_control_none, null)); + backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_science, R.mipmap.icon_green_science, fileDir + "science.mp4")); + backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_beach, R.mipmap.icon_green_bg_beach, fileDir + "beach.mp4")); + backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_classroom, R.mipmap.icon_green_bg_classroom, fileDir + "classroom.mp4")); + backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_ink, R.mipmap.icon_green_ink_painting, fileDir + "ink_painting.mp4")); + backgroundBeans.add(new BgSegGreenBackgroundBean(R.string.bg_seg_green_forest, R.mipmap.icon_green_bg_forest, fileDir + "forest.mp4")); + return backgroundBeans; + } + + /** + * 缓存自定义安全区域图片 + * + * @param path + */ + public static void saveCachePortraitSegment(String path) { + SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(GREEN_SAFE_AREA_CUSTOM, MODE_PRIVATE); + sp.edit().putString(GREEN_SAFE_AREA_CUSTOM, path).apply(); + } + + /** + * 获取自定义安全区域图片 + * + * @return + */ + public static String getCachePortraitSegment() { + SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(GREEN_SAFE_AREA_CUSTOM, MODE_PRIVATE); + return sp.getString(GREEN_SAFE_AREA_CUSTOM, ""); + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/FaceBeautySource.java b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/FaceBeautySource.java index 4cd981b63..7cc3b6e0f 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/FaceBeautySource.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/FaceBeautySource.java @@ -1,18 +1,24 @@ package com.yunbao.faceunity.repo; + import com.faceunity.core.controller.facebeauty.FaceBeautyParam; import com.faceunity.core.entity.FUBundleData; +import com.faceunity.core.enumeration.FUFaceBeautyMultiModePropertyEnum; +import com.faceunity.core.enumeration.FUFaceBeautyPropertyModeEnum; +import com.faceunity.core.faceunity.FURenderKit; import com.faceunity.core.model.facebeauty.FaceBeauty; -import com.faceunity.core.model.facebeauty.FaceBeautyBlurTypeEnum; import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum; import com.yunbao.faceunity.R; +import com.yunbao.faceunity.data.FaceBeautyData; +import com.yunbao.faceunity.data.FaceBeautyDataFactory; 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.utils.FUUtils; import com.yunbao.faceunity.utils.FaceUnityConfig; import com.yunbao.faceunity.utils.FuDeviceUtils; -import java.io.File; import java.util.ArrayList; import java.util.HashMap; @@ -22,36 +28,76 @@ import java.util.HashMap; */ public class FaceBeautySource { - public static String BUNDLE_FACE_BEAUTIFICATION = "graphics" + File.separator + "face_beautification.bundle"; - - + private static ArrayList filters = new ArrayList<>(); + private static FaceBeautyData faceBeautyData; /** * 获取默认推荐美颜模型 + * 一个app生命周期请求一次 * * @return */ public static FaceBeauty getDefaultFaceBeauty() { - FaceBeauty recommendFaceBeauty = new FaceBeauty(new FUBundleData(BUNDLE_FACE_BEAUTIFICATION)); - recommendFaceBeauty.setFilterName(FaceBeautyFilterEnum.ZIRAN_1); - recommendFaceBeauty.setFilterIntensity(0.4); - /*美肤*/ - recommendFaceBeauty.setBlurType(FaceBeautyBlurTypeEnum.FineSkin); - recommendFaceBeauty.setSharpenIntensity(0.2); - recommendFaceBeauty.setColorIntensity(0.3); - recommendFaceBeauty.setRedIntensity(0.3); - recommendFaceBeauty.setBlurIntensity(4.2); - /*美型*/ - recommendFaceBeauty.setFaceShapeIntensity(1.0); - recommendFaceBeauty.setEyeEnlargingIntensityV2(0.4); - recommendFaceBeauty.setCheekVIntensity(0.5); - recommendFaceBeauty.setNoseIntensityV2(0.5); - recommendFaceBeauty.setForHeadIntensityV2(0.3); - recommendFaceBeauty.setMouthIntensityV2(0.4); - recommendFaceBeauty.setChinIntensity(0.3); + FaceBeauty recommendFaceBeauty = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + if (FaceUnityConfig.OPEN_FACE_BEAUTY_TO_FILE) + faceBeautyData = FUUtils.loadFaceBeautyData(); + if (faceBeautyData != null) { + //有本地缓存 + FaceBeautyDataFactory.setDiskCurrentStyleIndex(faceBeautyData.styleTypeIndex); + FUUtils.setFaceBeauty(faceBeautyData, recommendFaceBeauty); + } else { + //没有本地缓存 + recommendFaceBeauty.setFilterName(FaceBeautyFilterEnum.ZIRAN_2); + recommendFaceBeauty.setFilterIntensity(0.4); + /*美肤*/ + recommendFaceBeauty.setSharpenIntensity(0.2); + recommendFaceBeauty.setColorIntensity(0.3); + recommendFaceBeauty.setRedIntensity(0.3); + recommendFaceBeauty.setBlurIntensity(4.2); + /*美型*/ + recommendFaceBeauty.setFaceShapeIntensity(1.0); + recommendFaceBeauty.setEyeEnlargingIntensity(0.4); + recommendFaceBeauty.setCheekVIntensity(0.5); + recommendFaceBeauty.setNoseIntensity(0.5); + recommendFaceBeauty.setForHeadIntensity(0.3); + recommendFaceBeauty.setMouthIntensity(0.4); + recommendFaceBeauty.setChinIntensity(0.3); + //性能最优策略 + if (FaceUnityConfig.DEVICE_LEVEL > FuDeviceUtils.DEVICE_LEVEL_MID) { + setFaceBeautyPropertyMode(recommendFaceBeauty); + } + } + return recommendFaceBeauty; } + /** + * 高端机的时候,开启4个相对吃性能的模式 + * 1.祛黑眼圈 MODE2 + * 2.祛法令纹 MODE2 + * 3.大眼 MODE3 + * 4.嘴型 MODE3 + */ + private static void setFaceBeautyPropertyMode(FaceBeauty faceBeauty) { + /* + * 多模式属性 + * 属性名称|支持模式|默认模式|最早支持版本 + * 美白 colorIntensity|MODE1 MODE2|MODE2|MODE2 8.2.0; + * 祛黑眼圈 removePouchIntensity|MODE1 MODE2|MODE2|MODE2 8.2.0; + * 祛法令纹 removeLawPatternIntensity|MODE1 MODE1|MODE2|MODE2 8.2.0; + * 窄脸程度 cheekNarrowIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0; + * 小脸程度 cheekSmallIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0; + * 大眼程度 eyeEnlargingIntensity|MODE1 MODE2 MODE3|MODE3|MODE2 8.0.0;MODE3 8.2.0; + * 额头调整程度 forHeadIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0; + * 瘦鼻程度 noseIntensity|MODE1 MODE2|MODE2|MODE2 8.0.0; + * 嘴巴调整程度 mouthIntensity|MODE1 MODE2 MODE3|MODE3|MODE2 8.0.0;MODE3 8.2.0; + */ + faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.REMOVE_POUCH_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE2); + faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.REMOVE_NASOLABIAL_FOLDS_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE2); + faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.EYE_ENLARGING_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE3); + faceBeauty.addPropertyMode(FUFaceBeautyMultiModePropertyEnum.MOUTH_INTENSITY, FUFaceBeautyPropertyModeEnum.MODE3); + } + /** * 初始化美肤参数 @@ -98,15 +144,14 @@ public class FaceBeautySource { params.add( new FaceBeautyBean( FaceBeautyParam.REMOVE_POUCH_INTENSITY, R.string.beauty_micro_pouch, - R.drawable.icon_beauty_skin_dark_circles_close_selector, R.drawable.icon_beauty_skin_dark_circles_open_selector - ) + R.drawable.icon_beauty_skin_dark_circles_close_selector, R.drawable.icon_beauty_skin_dark_circles_open_selector) ); params.add( new FaceBeautyBean( FaceBeautyParam.REMOVE_NASOLABIAL_FOLDS_INTENSITY, R.string.beauty_micro_nasolabial, - R.drawable.icon_beauty_skin_wrinkle_close_selector, R.drawable.icon_beauty_skin_wrinkle_open_selector - ) + R.drawable.icon_beauty_skin_wrinkle_close_selector, R.drawable.icon_beauty_skin_wrinkle_open_selector) ); + return params; } @@ -117,6 +162,13 @@ public class FaceBeautySource { */ public static ArrayList buildShapeParams() { ArrayList params = new ArrayList<>(); +// params.add( +// new FaceBeautyBean( +// "", R.string.avatar_face_face, +// R.drawable.icon_beauty_shape_face_shape_close_selector, R.drawable.icon_beauty_shape_face_shape_open_selector, FaceBeautyBean.ButtonType.SUB_ITEM_BUTTON +// ) +// ); + //瘦脸 params.add( new FaceBeautyBean( @@ -257,6 +309,64 @@ public class FaceBeautySource { return params; } + /** + * 加载脸型子项 + * + * @return + */ + public static ArrayList buildFaceShapeSubItemParams() { + return buildSubItemParams(FaceBeautyParam.FACE_SHAPE); + } + + public static ArrayList buildSubItemParams(String key) { + ArrayList params = new ArrayList<>(); +// if (key != null && !key.isEmpty()) { +// if (key.equals(FaceBeautyParam.FACE_SHAPE)) { +// //返回 +// params.add( +// new FaceBeautyBean( +// "", R.string.back, +// R.mipmap.icon_beauty_back, R.mipmap.icon_beauty_back, FaceBeautyBean.ButtonType.BACK_BUTTON +// ) +// ); +// +// //自然 V脸 -> 自然脸 +// params.add( +// new FaceBeautyBean( +// FaceBeautyParam.CHEEK_V_INTENSITY, R.string.beauty_box_cheek_natural, +// R.drawable.icon_beauty_shape_face_natural_close_selector, R.drawable.icon_beauty_shape_face_natural_open_selector +// ) +// ); +// +// //女神 瘦脸 -> 女神脸 +// params.add( +// new FaceBeautyBean( +// FaceBeautyParam.CHEEK_THINNING_INTENSITY, R.string.beauty_box_cheek_goddess, +// R.drawable.icon_beauty_shape_face_goddess_close_selector, R.drawable.icon_beauty_shape_face_goddess_open_selector +// ) +// ); +// +// //长脸 +// params.add( +// new FaceBeautyBean( +// FaceBeautyParam.CHEEK_LONG_INTENSITY, R.string.beauty_box_cheek_long_face, +// R.drawable.icon_beauty_shape_face_long_close_selector, R.drawable.icon_beauty_shape_face_long_open_selector +// ) +// ); +// +// //圆脸 +// params.add( +// new FaceBeautyBean( +// FaceBeautyParam.CHEEK_CIRCLE_INTENSITY, R.string.beauty_box_cheek_round_face, +// R.drawable.icon_beauty_shape_face_round_close_selector, R.drawable.icon_beauty_shape_face_round_open_selector +// ) +// ); +// } +// } + + return params; + } + /** * 初始化参数扩展列表 * @@ -308,14 +418,279 @@ public class FaceBeautySource { * @return ArrayList */ public static ArrayList buildFilters() { - ArrayList filters = new ArrayList<>(); + if (!filters.isEmpty()) { + return filters; + } filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ORIGIN, R.mipmap.icon_beauty_filter_cancel, R.string.origin, 0.0)); - filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_1, R.mipmap.icon_beauty_filter_natural_1, R.string.ziran_1)); - filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_1, R.mipmap.icon_beauty_filter_texture_gray_1, R.string.zhiganhui_1)); - filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_1, R.mipmap.icon_beauty_filter_bailiang_1, R.string.bailiang_1)); - filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_1, R.mipmap.icon_beauty_filter_fennen_1, R.string.fennen_1)); - filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_1, R.mipmap.icon_beauty_filter_lengsediao_1, R.string.lengsediao_1)); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_1, R.mipmap.icon_beauty_filter_natural_1, R.string.ziran_1,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_2, R.mipmap.icon_beauty_filter_natural_2, R.string.ziran_2,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_3, R.mipmap.icon_beauty_filter_natural_3, R.string.ziran_3,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_4, R.mipmap.icon_beauty_filter_natural_4, R.string.ziran_4,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_4))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_5, R.mipmap.icon_beauty_filter_natural_5, R.string.ziran_5,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_5))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_6, R.mipmap.icon_beauty_filter_natural_6, R.string.ziran_6,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_6))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_7, R.mipmap.icon_beauty_filter_natural_7, R.string.ziran_7,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_7))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZIRAN_8, R.mipmap.icon_beauty_filter_natural_8, R.string.ziran_8,getDiskFilterValue(FaceBeautyFilterEnum.ZIRAN_8))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_1, R.mipmap.icon_beauty_filter_texture_gray_1, R.string.zhiganhui_1,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_2, R.mipmap.icon_beauty_filter_texture_gray_2, R.string.zhiganhui_2,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_3, R.mipmap.icon_beauty_filter_texture_gray_3, R.string.zhiganhui_3,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_4, R.mipmap.icon_beauty_filter_texture_gray_4, R.string.zhiganhui_4,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_4))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_5, R.mipmap.icon_beauty_filter_texture_gray_5, R.string.zhiganhui_5,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_5))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_6, R.mipmap.icon_beauty_filter_texture_gray_6, R.string.zhiganhui_6,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_6))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_7, R.mipmap.icon_beauty_filter_texture_gray_7, R.string.zhiganhui_7,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_7))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.ZHIGANHUI_8, R.mipmap.icon_beauty_filter_texture_gray_8, R.string.zhiganhui_8,getDiskFilterValue(FaceBeautyFilterEnum.ZHIGANHUI_8))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_1, R.mipmap.icon_beauty_filter_peach_1, R.string.mitao_1,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_2, R.mipmap.icon_beauty_filter_peach_2, R.string.mitao_2,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_3, R.mipmap.icon_beauty_filter_peach_3, R.string.mitao_3,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_4, R.mipmap.icon_beauty_filter_peach_4, R.string.mitao_4,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_4))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_5, R.mipmap.icon_beauty_filter_peach_5, R.string.mitao_5,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_5))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_6, R.mipmap.icon_beauty_filter_peach_6, R.string.mitao_6,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_6))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_7, R.mipmap.icon_beauty_filter_peach_7, R.string.mitao_7,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_7))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.MITAO_8, R.mipmap.icon_beauty_filter_peach_8, R.string.mitao_8,getDiskFilterValue(FaceBeautyFilterEnum.MITAO_8))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_1, R.mipmap.icon_beauty_filter_bailiang_1, R.string.bailiang_1,getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_2, R.mipmap.icon_beauty_filter_bailiang_2, R.string.bailiang_2,getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_3, R.mipmap.icon_beauty_filter_bailiang_3, R.string.bailiang_3,getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_4, R.mipmap.icon_beauty_filter_bailiang_4, R.string.bailiang_4,getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_4))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_5, R.mipmap.icon_beauty_filter_bailiang_5, R.string.bailiang_5,getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_5))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_6, R.mipmap.icon_beauty_filter_bailiang_6, R.string.bailiang_6,getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_6))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.BAILIANG_7, R.mipmap.icon_beauty_filter_bailiang_7, R.string.bailiang_7,getDiskFilterValue(FaceBeautyFilterEnum.BAILIANG_7))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_1, R.mipmap.icon_beauty_filter_fennen_1, R.string.fennen_1,getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_2, R.mipmap.icon_beauty_filter_fennen_2, R.string.fennen_2,getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_3, R.mipmap.icon_beauty_filter_fennen_3, R.string.fennen_3,getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_5, R.mipmap.icon_beauty_filter_fennen_5, R.string.fennen_5,getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_5))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_6, R.mipmap.icon_beauty_filter_fennen_6, R.string.fennen_6,getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_6))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_7, R.mipmap.icon_beauty_filter_fennen_7, R.string.fennen_7,getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_7))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.FENNEN_8, R.mipmap.icon_beauty_filter_fennen_8, R.string.fennen_8,getDiskFilterValue(FaceBeautyFilterEnum.FENNEN_8))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_1, R.mipmap.icon_beauty_filter_lengsediao_1, R.string.lengsediao_1,getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_2, R.mipmap.icon_beauty_filter_lengsediao_2, R.string.lengsediao_2,getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_3, R.mipmap.icon_beauty_filter_lengsediao_3, R.string.lengsediao_3,getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_4, R.mipmap.icon_beauty_filter_lengsediao_4, R.string.lengsediao_4,getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_4))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_7, R.mipmap.icon_beauty_filter_lengsediao_7, R.string.lengsediao_7,getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_7))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_8, R.mipmap.icon_beauty_filter_lengsediao_8, R.string.lengsediao_8,getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_8))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.LENGSEDIAO_11, R.mipmap.icon_beauty_filter_lengsediao_11, R.string.lengsediao_11,getDiskFilterValue(FaceBeautyFilterEnum.LENGSEDIAO_11))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.NUANSEDIAO_1, R.mipmap.icon_beauty_filter_nuansediao_1, R.string.nuansediao_1,getDiskFilterValue(FaceBeautyFilterEnum.NUANSEDIAO_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.NUANSEDIAO_2, R.mipmap.icon_beauty_filter_nuansediao_2, R.string.nuansediao_2,getDiskFilterValue(FaceBeautyFilterEnum.NUANSEDIAO_2))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_1, R.mipmap.icon_beauty_filter_gexing_1, R.string.gexing_1,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_2, R.mipmap.icon_beauty_filter_gexing_2, R.string.gexing_2,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_3, R.mipmap.icon_beauty_filter_gexing_3, R.string.gexing_3,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_4, R.mipmap.icon_beauty_filter_gexing_4, R.string.gexing_4,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_4))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_5, R.mipmap.icon_beauty_filter_gexing_5, R.string.gexing_5,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_5))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_7, R.mipmap.icon_beauty_filter_gexing_7, R.string.gexing_7,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_7))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_10, R.mipmap.icon_beauty_filter_gexing_10, R.string.gexing_10,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_10))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.GEXING_11, R.mipmap.icon_beauty_filter_gexing_11, R.string.gexing_11,getDiskFilterValue(FaceBeautyFilterEnum.GEXING_11))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_1, R.mipmap.icon_beauty_filter_xiaoqingxin_1, R.string.xiaoqingxin_1,getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_3, R.mipmap.icon_beauty_filter_xiaoqingxin_3, R.string.xiaoqingxin_3,getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_4, R.mipmap.icon_beauty_filter_xiaoqingxin_4, R.string.xiaoqingxin_4,getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_4))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.XIAOQINGXIN_6, R.mipmap.icon_beauty_filter_xiaoqingxin_6, R.string.xiaoqingxin_6,getDiskFilterValue(FaceBeautyFilterEnum.XIAOQINGXIN_6))); + + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_1, R.mipmap.icon_beauty_filter_heibai_1, R.string.heibai_1,getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_1))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_2, R.mipmap.icon_beauty_filter_heibai_2, R.string.heibai_2,getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_2))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_3, R.mipmap.icon_beauty_filter_heibai_3, R.string.heibai_3,getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_3))); + filters.add(new FaceBeautyFilterBean(FaceBeautyFilterEnum.HEIBAI_4, R.mipmap.icon_beauty_filter_heibai_4, R.string.heibai_4,getDiskFilterValue(FaceBeautyFilterEnum.HEIBAI_4))); + return filters; } + /** + * 从磁盘获取所有项滤镜强度 + * @param key + * @return + */ + private static double getDiskFilterValue(String key) { + if (faceBeautyData != null) { + return faceBeautyData.filterMap.get(key); + } else { + return 0.4; + } + } + + private static final String CONFIG_BIAOZHUN = "biaozhun"; + private static final String CONFIG_HUAJIAO = "huajiao"; + private static final String CONFIG_KUAISHOU = "kuaishou"; + private static final String CONFIG_QINGYAN = "qingyan"; + private static final String CONFIG_SHANGTANG = "shangtang"; + private static final String CONFIG_YINGKE = "yingke"; + private static final String CONFIG_ZIJIETIAODONG = "zijietiaodong"; + + + /** + * 初始化风格推荐 + * + * @return ArrayList + */ + public static ArrayList buildStylesParams() { + ArrayList params = new ArrayList<>(); + params.add(new FaceBeautyStyleBean(CONFIG_KUAISHOU, R.drawable.icon_beauty_style_1_selector, R.string.beauty_face_style_1)); + params.add(new FaceBeautyStyleBean(CONFIG_QINGYAN, R.drawable.icon_beauty_style_2_selector, R.string.beauty_face_style_2)); + params.add(new FaceBeautyStyleBean(CONFIG_ZIJIETIAODONG, R.drawable.icon_beauty_style_3_selector, R.string.beauty_face_style_3)); + params.add(new FaceBeautyStyleBean(CONFIG_HUAJIAO, R.drawable.icon_beauty_style_4_selector, R.string.beauty_face_style_4)); + params.add(new FaceBeautyStyleBean(CONFIG_YINGKE, R.drawable.icon_beauty_style_5_selector, R.string.beauty_face_style_5)); + params.add(new FaceBeautyStyleBean(CONFIG_SHANGTANG, R.drawable.icon_beauty_style_6_selector, R.string.beauty_face_style_6)); + params.add(new FaceBeautyStyleBean(CONFIG_BIAOZHUN, R.drawable.icon_beauty_style_7_selector, R.string.beauty_face_style_7)); + return params; + } + + /** + * 风格对应参数配置 + */ + public static HashMap styleParams = new HashMap() { + { + put(CONFIG_KUAISHOU, () -> { + FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + model.setFaceShapeIntensity(1.0); + model.setColorIntensity(0.5); + model.setBlurIntensity(3.6); + model.setEyeBrightIntensity(0.35); + model.setToothIntensity(0.25); + model.setCheekThinningIntensity(0.45); + model.setCheekVIntensity(0.08); + model.setCheekSmallIntensity(0.05); + model.setEyeEnlargingIntensity(0.3); + FaceBeautyDataFactory.faceBeauty = model; + FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty); + + }); + put(CONFIG_QINGYAN, () -> { + FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + model.setFaceShapeIntensity(1.0); + model.setFilterName(FaceBeautyFilterEnum.ZIRAN_3); + model.setFilterIntensity(0.3); + model.setColorIntensity(0.4); + model.setRedIntensity(0.2); + model.setBlurIntensity(3.6); + model.setEyeBrightIntensity(0.5); + model.setToothIntensity(0.4); + model.setCheekThinningIntensity(0.3); + model.setNoseIntensity(0.5); + model.setEyeEnlargingIntensity(0.25); + FaceBeautyDataFactory.faceBeauty = model; + FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty); + }); + put(CONFIG_ZIJIETIAODONG, () -> { + FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + model.setFaceShapeIntensity(1.0); + model.setColorIntensity(0.4); + model.setRedIntensity(0.3); + model.setBlurIntensity(2.4); + model.setCheekThinningIntensity(0.3); + model.setCheekSmallIntensity(0.15); + model.setEyeEnlargingIntensity(0.65); + model.setNoseIntensity(0.3); + FaceBeautyDataFactory.faceBeauty = model; + FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty); + }); + put(CONFIG_HUAJIAO, () -> { + FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + model.setFaceShapeIntensity(1.0); + model.setColorIntensity(0.7); + model.setBlurIntensity(3.9); + model.setCheekThinningIntensity(0.3); + model.setCheekSmallIntensity(0.05); + model.setEyeEnlargingIntensity(0.65); + FaceBeautyDataFactory.faceBeauty = model; + FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty); + }); + put(CONFIG_YINGKE, () -> { + FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + model.setFaceShapeIntensity(1.0); + model.setFilterName(FaceBeautyFilterEnum.FENNEN_2); + model.setFilterIntensity(0.5); + model.setColorIntensity(0.6); + model.setBlurIntensity(3.0); + model.setCheekThinningIntensity(0.5); + model.setEyeEnlargingIntensity(0.65); + FaceBeautyDataFactory.faceBeauty = model; + FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty); + }); + put(CONFIG_SHANGTANG, () -> { + FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + model.setFaceShapeIntensity(1.0); + model.setFilterName(FaceBeautyFilterEnum.FENNEN_2); + model.setFilterIntensity(0.8); + model.setColorIntensity(0.7); + model.setBlurIntensity(4.2); + model.setEyeEnlargingIntensity(0.6); + model.setCheekThinningIntensity(0.3); + FaceBeautyDataFactory.faceBeauty = model; + FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty); + }); + put(CONFIG_BIAOZHUN, () -> { + FaceBeauty model = new FaceBeauty(new FUBundleData(FaceUnityConfig.BUNDLE_FACE_BEAUTIFICATION)); + model.setFaceShapeIntensity(1.0); + model.setFilterName(FaceBeautyFilterEnum.ZIRAN_5); + model.setFilterIntensity(0.55); + model.setColorIntensity(0.2); + model.setRedIntensity(0.65); + model.setBlurIntensity(3.3); + model.setCheekSmallIntensity(0.05); + model.setCheekThinningIntensity(0.1); + FaceBeautyDataFactory.faceBeauty = model; + FURenderKit.getInstance().setFaceBeauty(FaceBeautyDataFactory.faceBeauty); + }); + } + + }; + + /** + * 克隆模型 + * + * @param faceBeauty + * @return + */ + public static FaceBeauty clone(FaceBeauty faceBeauty) { + FaceBeauty cloneFaceBeauty = new FaceBeauty(new FUBundleData(faceBeauty.getControlBundle().getPath())); + /*滤镜*/ + cloneFaceBeauty.setFilterName(faceBeauty.getFilterName()); + cloneFaceBeauty.setFilterIntensity(faceBeauty.getFilterIntensity()); + /*美肤*/ + cloneFaceBeauty.setBlurIntensity(faceBeauty.getBlurIntensity()); + cloneFaceBeauty.setEnableHeavyBlur(faceBeauty.getEnableHeavyBlur()); + cloneFaceBeauty.setEnableSkinDetect(faceBeauty.getEnableSkinDetect()); + cloneFaceBeauty.setNonSkinBlurIntensity(faceBeauty.getNonSkinBlurIntensity()); + cloneFaceBeauty.setBlurType(faceBeauty.getBlurType()); + cloneFaceBeauty.setEnableBlurUseMask(faceBeauty.getEnableBlurUseMask()); + cloneFaceBeauty.setColorIntensity(faceBeauty.getColorIntensity()); + cloneFaceBeauty.setRedIntensity(faceBeauty.getRedIntensity()); + cloneFaceBeauty.setSharpenIntensity(faceBeauty.getSharpenIntensity()); + cloneFaceBeauty.setEyeBrightIntensity(faceBeauty.getEyeBrightIntensity()); + cloneFaceBeauty.setToothIntensity(faceBeauty.getToothIntensity()); + cloneFaceBeauty.setRemovePouchIntensity(faceBeauty.getRemovePouchIntensity()); + cloneFaceBeauty.setRemoveLawPatternIntensity(faceBeauty.getRemoveLawPatternIntensity()); + /*美型*/ + cloneFaceBeauty.setFaceShape(faceBeauty.getFaceShape()); + cloneFaceBeauty.setFaceShapeIntensity(faceBeauty.getFaceShapeIntensity()); + cloneFaceBeauty.setCheekThinningIntensity(faceBeauty.getCheekThinningIntensity()); + cloneFaceBeauty.setCheekVIntensity(faceBeauty.getCheekVIntensity()); + cloneFaceBeauty.setCheekLongIntensity(faceBeauty.getCheekLongIntensity()); + cloneFaceBeauty.setCheekCircleIntensity(faceBeauty.getCheekCircleIntensity()); + cloneFaceBeauty.setCheekNarrowIntensity(faceBeauty.getCheekNarrowIntensity()); + cloneFaceBeauty.setCheekShortIntensity(faceBeauty.getCheekShortIntensity()); + cloneFaceBeauty.setCheekSmallIntensity(faceBeauty.getCheekSmallIntensity()); + cloneFaceBeauty.setCheekBonesIntensity(faceBeauty.getCheekBonesIntensity()); + cloneFaceBeauty.setLowerJawIntensity(faceBeauty.getLowerJawIntensity()); + cloneFaceBeauty.setEyeEnlargingIntensity(faceBeauty.getEyeEnlargingIntensity()); + cloneFaceBeauty.setChinIntensity(faceBeauty.getChinIntensity()); + cloneFaceBeauty.setForHeadIntensity(faceBeauty.getForHeadIntensity()); + cloneFaceBeauty.setNoseIntensity(faceBeauty.getNoseIntensity()); + cloneFaceBeauty.setMouthIntensity(faceBeauty.getMouthIntensity()); + cloneFaceBeauty.setCanthusIntensity(faceBeauty.getCanthusIntensity()); + cloneFaceBeauty.setEyeSpaceIntensity(faceBeauty.getEyeSpaceIntensity()); + cloneFaceBeauty.setEyeRotateIntensity(faceBeauty.getEyeRotateIntensity()); + cloneFaceBeauty.setLongNoseIntensity(faceBeauty.getLongNoseIntensity()); + cloneFaceBeauty.setPhiltrumIntensity(faceBeauty.getPhiltrumIntensity()); + cloneFaceBeauty.setSmileIntensity(faceBeauty.getSmileIntensity()); + cloneFaceBeauty.setEyeCircleIntensity(faceBeauty.getEyeCircleIntensity()); + cloneFaceBeauty.setBrowHeightIntensity(faceBeauty.getBrowHeightIntensity()); + cloneFaceBeauty.setBrowSpaceIntensity(faceBeauty.getBrowSpaceIntensity()); + cloneFaceBeauty.setChangeFramesIntensity(faceBeauty.getChangeFramesIntensity()); + return cloneFaceBeauty; + } + } diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/LightMakeupSource.java b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/LightMakeupSource.java new file mode 100644 index 000000000..54af740c5 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/LightMakeupSource.java @@ -0,0 +1,402 @@ +package com.yunbao.faceunity.repo; + +import android.content.Context; + + +import com.faceunity.core.entity.FUBundleData; +import com.faceunity.core.entity.FUColorRGBData; +import com.faceunity.core.faceunity.FURenderKit; +import com.faceunity.core.model.facebeauty.FaceBeautyFilterEnum; +import com.faceunity.core.model.littleMakeup.LightMakeup; +import com.yunbao.faceunity.R; +import com.yunbao.faceunity.entity.LightMakeupBean; +import com.yunbao.faceunity.utils.FaceUnityConfig; +import com.yunbao.faceunity.utils.FaceUnityData; +import com.yunbao.faceunity.utils.FileUtils; + +import org.json.JSONArray; +import org.json.JSONException; +import org.json.JSONObject; + +import java.io.IOException; +import java.io.InputStream; +import java.util.ArrayList; +import java.util.HashMap; + +/** + * DESC:轻美妆数据构造 + * Created on 2021/3/27 + */ +public class LightMakeupSource { + + /** + * 构造轻美妆队列 + * + * @return + */ + public static ArrayList buildLightMakeup() { + ArrayList makeups = new ArrayList<>(); + makeups.add(new LightMakeupBean(R.string.makeup_radio_remove, R.mipmap.icon_control_none, null, 0.0, FaceBeautyFilterEnum.ZIRAN_2, 0.4)); + /*桃花*/ + makeups.add(new LightMakeupBean(R.string.makeup_peach_blossom, R.mipmap.icon_light_makeup_peachblossom, "taohua", 0.9, FaceBeautyFilterEnum.FENNEN_3, 0.9)); + /*西柚*/ + makeups.add(new LightMakeupBean(R.string.makeup_grapefruit, R.mipmap.icon_light_makeup_grapefruit, "xiyou", 1.0, FaceBeautyFilterEnum.LENGSEDIAO_4, 1.0)); + /*清透*/ + makeups.add(new LightMakeupBean(R.string.makeup_clear, R.mipmap.icon_light_makeup_clear, "qingtou", 0.9, FaceBeautyFilterEnum.XIAOQINGXIN_1, 0.9)); + /*男友*/ + makeups.add(new LightMakeupBean(R.string.makeup_boyfriend, R.mipmap.icon_light_makeup_boyfriend, "nanyou", 1.0, FaceBeautyFilterEnum.XIAOQINGXIN_3, 1.0)); + return makeups; + } + + + /** + * 风格对应参数配置 + */ + public static HashMap LightMakeupParams = new HashMap() { + { + put("taohua", () -> { + LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP)); + lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_01.path); + lightMakeup.setBlusherIntensity(0.9); + lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_01.path); + lightMakeup.setEyeShadowIntensity(0.9); + lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_01.path); + lightMakeup.setEyeBrowIntensity(0.5); + lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_01.getLipColorRGBData()); + lightMakeup.setLipIntensity(0.9); + FURenderKit.getInstance().setLightMakeup(lightMakeup); + }); + put("xiyou", () -> { + LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP)); + lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_23.path); + lightMakeup.setBlusherIntensity(1.0); + lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_21.path); + lightMakeup.setEyeShadowIntensity(0.75); + lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_19.path); + lightMakeup.setEyeBrowIntensity(0.6); + lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_21.getLipColorRGBData()); + lightMakeup.setLipIntensity(0.8); + FURenderKit.getInstance().setLightMakeup(lightMakeup); + }); + put("qingtou", () -> { + LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP)); + lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_22.path); + lightMakeup.setBlusherIntensity(0.9); + lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_20.path); + lightMakeup.setEyeShadowIntensity(0.65); + lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_18.path); + lightMakeup.setEyeBrowIntensity(0.45); + lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_20.getLipColorRGBData()); + lightMakeup.setLipIntensity(0.8); + FURenderKit.getInstance().setLightMakeup(lightMakeup); + }); + put("nanyou", () -> { + LightMakeup lightMakeup = new LightMakeup(new FUBundleData(FaceUnityConfig.BUNDLE_LIGHT_MAKEUP)); + lightMakeup.setBlusherTex(LightMakeUpEnum.MAKEUP_BLUSHER_20.path); + lightMakeup.setBlusherIntensity(0.8); + lightMakeup.setEyeShadowTex(LightMakeUpEnum.MAKEUP_EYE_SHADOW_18.path); + lightMakeup.setEyeShadowIntensity(0.9); + lightMakeup.setEyeBrowTex(LightMakeUpEnum.MAKEUP_EYEBROW_16.path); + lightMakeup.setEyeBrowIntensity(0.65); + lightMakeup.setLipColor(LightMakeUpEnum.MAKEUP_LIPSTICK_18.getLipColorRGBData()); + lightMakeup.setLipIntensity(1.0); + FURenderKit.getInstance().setLightMakeup(lightMakeup); + }); + } + + }; + + + + + + //region 轻美妆效果枚举 + public enum LightMakeUpEnum { + /** + * 美妆项,前几项是预置的效果 + * 排在列表最前方,顺序为桃花妆、雀斑妆、朋克妆(其中朋克没有腮红,3个妆容的眼线、眼睫毛共用1个的) + */ + // 腮红 + MAKEUP_BLUSHER_01("MAKEUP_BLUSHER_01", "light_makeup/blusher/mu_blush_01.png", R.mipmap.icon_light_makeup_blush_01, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_02("MAKEUP_BLUSHER_02", "light_makeup/blusher/mu_blush_02.png", R.mipmap.icon_light_makeup_blush_02, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_03("MAKEUP_BLUSHER_03", "light_makeup/blusher/mu_blush_03.png", R.mipmap.icon_light_makeup_blush_03, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_04("MAKEUP_BLUSHER_04", "light_makeup/blusher/mu_blush_04.png", R.mipmap.icon_light_makeup_blush_04, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_05("MAKEUP_BLUSHER_05", "light_makeup/blusher/mu_blush_05.png", R.mipmap.icon_light_makeup_blush_05, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_06("MAKEUP_BLUSHER_06", "light_makeup/blusher/mu_blush_06.png", R.mipmap.icon_light_makeup_blush_06, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_07("MAKEUP_BLUSHER_07", "light_makeup/blusher/mu_blush_07.png", R.mipmap.icon_light_makeup_blush_07, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_08("MAKEUP_BLUSHER_08", "light_makeup/blusher/mu_blush_08.png", R.mipmap.icon_light_makeup_blush_08, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_09("MAKEUP_BLUSHER_09", "light_makeup/blusher/mu_blush_09.png", R.mipmap.icon_light_makeup_blush_09, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_10("MAKEUP_BLUSHER_10", "light_makeup/blusher/mu_blush_10.png", R.mipmap.icon_light_makeup_blush_10, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_11("MAKEUP_BLUSHER_11", "light_makeup/blusher/mu_blush_11.png", R.mipmap.icon_light_makeup_blush_11, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_12("MAKEUP_BLUSHER_12", "light_makeup/blusher/mu_blush_12.png", R.mipmap.icon_light_makeup_blush_12, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_13("MAKEUP_BLUSHER_13", "light_makeup/blusher/mu_blush_13.png", R.mipmap.icon_light_makeup_blush_13, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_14("MAKEUP_BLUSHER_14", "light_makeup/blusher/mu_blush_14.png", R.mipmap.icon_light_makeup_blush_14, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_15("MAKEUP_BLUSHER_15", "light_makeup/blusher/mu_blush_15.png", R.mipmap.icon_light_makeup_blush_15, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_16("MAKEUP_BLUSHER_16", "light_makeup/blusher/mu_blush_16.png", R.mipmap.icon_light_makeup_blush_16, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_17("MAKEUP_BLUSHER_17", "light_makeup/blusher/mu_blush_17.png", R.mipmap.icon_light_makeup_blush_17, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_18("MAKEUP_BLUSHER_18", "light_makeup/blusher/mu_blush_18.png", R.mipmap.icon_light_makeup_blush_18, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_19("MAKEUP_BLUSHER_19", "light_makeup/blusher/mu_blush_19.png", R.mipmap.icon_light_makeup_blush_19, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_20("MAKEUP_BLUSHER_20", "light_makeup/blusher/mu_blush_20.png", R.mipmap.icon_light_makeup_blush_20, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_21("MAKEUP_BLUSHER_21", "light_makeup/blusher/mu_blush_21.png", R.mipmap.icon_light_makeup_blush_21, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_22("MAKEUP_BLUSHER_22", "light_makeup/blusher/mu_blush_22.png", R.mipmap.icon_light_makeup_blush_22, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_23("MAKEUP_BLUSHER_23", "light_makeup/blusher/mu_blush_23.png", R.mipmap.icon_light_makeup_blush_23, R.string.makeup_radio_blusher), + + MAKEUP_BLUSHER_24("MAKEUP_BLUSHER_24", "light_makeup/blusher/mu_blush_24.png", R.mipmap.icon_light_makeup_blush_24, R.string.makeup_radio_blusher), + + // 眉毛 + MAKEUP_EYEBROW_01("MAKEUP_EYEBROW_01", "light_makeup/eyebrow/mu_eyebrow_01.png", R.mipmap.icon_light_makeup_eyebrow_01, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_02("MAKEUP_EYEBROW_02", "light_makeup/eyebrow/mu_eyebrow_02.png", R.mipmap.icon_light_makeup_eyebrow_02, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_03("MAKEUP_EYEBROW_03", "light_makeup/eyebrow/mu_eyebrow_03.png", R.mipmap.icon_light_makeup_eyebrow_03, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_04("MAKEUP_EYEBROW_04", "light_makeup/eyebrow/mu_eyebrow_04.png", R.mipmap.icon_light_makeup_eyebrow_04, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_05("MAKEUP_EYEBROW_05", "light_makeup/eyebrow/mu_eyebrow_05.png", R.mipmap.icon_light_makeup_eyebrow_05, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_06("MAKEUP_EYEBROW_06", "light_makeup/eyebrow/mu_eyebrow_06.png", R.mipmap.icon_light_makeup_eyebrow_06, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_07("MAKEUP_EYEBROW_07", "light_makeup/eyebrow/mu_eyebrow_07.png", R.mipmap.icon_light_makeup_eyebrow_07, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_08("MAKEUP_EYEBROW_08", "light_makeup/eyebrow/mu_eyebrow_08.png", R.mipmap.icon_light_makeup_eyebrow_08, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_09("MAKEUP_EYEBROW_09", "light_makeup/eyebrow/mu_eyebrow_09.png", R.mipmap.icon_light_makeup_eyebrow_09, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_10("MAKEUP_EYEBROW_10", "light_makeup/eyebrow/mu_eyebrow_10.png", R.mipmap.icon_light_makeup_eyebrow_10, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_11("MAKEUP_EYEBROW_11", "light_makeup/eyebrow/mu_eyebrow_11.png", R.mipmap.icon_light_makeup_eyebrow_11, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_12("MAKEUP_EYEBROW_12", "light_makeup/eyebrow/mu_eyebrow_12.png", R.mipmap.icon_light_makeup_eyebrow_12, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_13("MAKEUP_EYEBROW_13", "light_makeup/eyebrow/mu_eyebrow_13.png", R.mipmap.icon_light_makeup_eyebrow_13, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_14("MAKEUP_EYEBROW_14", "light_makeup/eyebrow/mu_eyebrow_14.png", R.mipmap.icon_light_makeup_eyebrow_14, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_15("MAKEUP_EYEBROW_15", "light_makeup/eyebrow/mu_eyebrow_15.png", R.mipmap.icon_light_makeup_eyebrow_15, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_16("MAKEUP_EYEBROW_16", "light_makeup/eyebrow/mu_eyebrow_16.png", R.mipmap.icon_light_makeup_eyebrow_16, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_17("MAKEUP_EYEBROW_17", "light_makeup/eyebrow/mu_eyebrow_17.png", R.mipmap.icon_light_makeup_eyebrow_17, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_18("MAKEUP_EYEBROW_18", "light_makeup/eyebrow/mu_eyebrow_18.png", R.mipmap.icon_light_makeup_eyebrow_18, R.string.makeup_radio_eyebrow), + + MAKEUP_EYEBROW_19("MAKEUP_EYEBROW_19", "light_makeup/eyebrow/mu_eyebrow_19.png", R.mipmap.icon_light_makeup_eyebrow_19, R.string.makeup_radio_eyebrow), + + // 睫毛 + MAKEUP_EYELASH_01("MAKEUP_EYELASH_01", "light_makeup/eyelash/mu_eyelash_01.png", R.mipmap.icon_light_makeup_eyelash_01, R.string.makeup_radio_eyelash), + + MAKEUP_EYELASH_02("MAKEUP_EYELASH_02", "light_makeup/eyelash/mu_eyelash_02.png", R.mipmap.icon_light_makeup_eyelash_02, R.string.makeup_radio_eyelash), + + MAKEUP_EYELASH_03("MAKEUP_EYELASH_03", "light_makeup/eyelash/mu_eyelash_03.png", R.mipmap.icon_light_makeup_eyelash_03, R.string.makeup_radio_eyelash), + + MAKEUP_EYELASH_04("MAKEUP_EYELASH_04", "light_makeup/eyelash/mu_eyelash_04.png", R.mipmap.icon_light_makeup_eyelash_04, R.string.makeup_radio_eyelash), + + MAKEUP_EYELASH_05("MAKEUP_EYELASH_05", "light_makeup/eyelash/mu_eyelash_05.png", R.mipmap.icon_light_makeup_eyelash_05, R.string.makeup_radio_eyelash), + + MAKEUP_EYELASH_06("MAKEUP_EYELASH_06", "light_makeup/eyelash/mu_eyelash_06.png", R.mipmap.icon_light_makeup_eyelash_06, R.string.makeup_radio_eyelash), + + MAKEUP_EYELASH_07("MAKEUP_EYELASH_07", "light_makeup/eyelash/mu_eyelash_07.png", R.mipmap.icon_light_makeup_eyelash_07, R.string.makeup_radio_eyelash), + + MAKEUP_EYELASH_08("MAKEUP_EYELASH_08", "light_makeup/eyelash/mu_eyelash_08.png", R.mipmap.icon_light_makeup_eyelash_08, R.string.makeup_radio_eyelash), + + // 眼线 + MAKEUP_EYELINER_01("MAKEUP_EYELINER_01", "light_makeup/eyeliner/mu_eyeliner_01.png", R.mipmap.icon_light_makeup_eyeliner_01, R.string.makeup_radio_eye_liner), + + MAKEUP_EYELINER_02("MAKEUP_EYELINER_02", "light_makeup/eyeliner/mu_eyeliner_02.png", R.mipmap.icon_light_makeup_eyeliner_02, R.string.makeup_radio_eye_liner), + + MAKEUP_EYELINER_03("MAKEUP_EYELINER_03", "light_makeup/eyeliner/mu_eyeliner_03.png", R.mipmap.icon_light_makeup_eyeliner_03, R.string.makeup_radio_eye_liner), + + MAKEUP_EYELINER_04("MAKEUP_EYELINER_04", "light_makeup/eyeliner/mu_eyeliner_04.png", R.mipmap.icon_light_makeup_eyeliner_04, R.string.makeup_radio_eye_liner), + + MAKEUP_EYELINER_05("MAKEUP_EYELINER_05", "light_makeup/eyeliner/mu_eyeliner_05.png", R.mipmap.icon_light_makeup_eyeliner_05, R.string.makeup_radio_eye_liner), + + MAKEUP_EYELINER_06("MAKEUP_EYELINER_06", "light_makeup/eyeliner/mu_eyeliner_06.png", R.mipmap.icon_light_makeup_eyeliner_06, R.string.makeup_radio_eye_liner), + + MAKEUP_EYELINER_07("MAKEUP_EYELINER_07", "light_makeup/eyeliner/mu_eyeliner_07.png", R.mipmap.icon_light_makeup_eyeliner_07, R.string.makeup_radio_eye_liner), + + MAKEUP_EYELINER_08("MAKEUP_EYELINER_08", "light_makeup/eyeliner/mu_eyeliner_08.png", R.mipmap.icon_light_makeup_eyeliner_08, R.string.makeup_radio_eye_liner), + + // 美瞳 + MAKEUP_EYEPUPIL_01("MAKEUP_EYEPUPIL_01", "light_makeup/eyepupil/mu_eyepupil_01.png", R.mipmap.icon_light_makeup_eyepupil_01, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_02("MAKEUP_EYEPUPIL_02", "light_makeup/eyepupil/mu_eyepupil_02.png", R.mipmap.icon_light_makeup_eyepupil_02, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_03("MAKEUP_EYEPUPIL_03", "light_makeup/eyepupil/mu_eyepupil_03.png", R.mipmap.icon_light_makeup_eyepupil_03, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_04("MAKEUP_EYEPUPIL_04", "light_makeup/eyepupil/mu_eyepupil_04.png", R.mipmap.icon_light_makeup_eyepupil_04, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_05("MAKEUP_EYEPUPIL_05", "light_makeup/eyepupil/mu_eyepupil_05.png", R.mipmap.icon_light_makeup_eyepupil_05, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_06("MAKEUP_EYEPUPIL_06", "light_makeup/eyepupil/mu_eyepupil_06.png", R.mipmap.icon_light_makeup_eyepupil_06, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_07("MAKEUP_EYEPUPIL_07", "light_makeup/eyepupil/mu_eyepupil_07.png", R.mipmap.icon_light_makeup_eyepupil_07, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_08("MAKEUP_EYEPUPIL_08", "light_makeup/eyepupil/mu_eyepupil_08.png", R.mipmap.icon_light_makeup_eyepupil_08, R.string.makeup_radio_contact_lens), + + MAKEUP_EYEPUPIL_09("MAKEUP_EYEPUPIL_09", "light_makeup/eyepupil/mu_eyepupil_09.png", R.mipmap.icon_light_makeup_eyepupil_09, R.string.makeup_radio_contact_lens), + + // 眼影 + MAKEUP_EYE_SHADOW_01("MAKEUP_EYESHADOW_01", "light_makeup/eyeshadow/mu_eyeshadow_01.png", R.mipmap.icon_light_makeup_eyeshadow_01, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_02("MAKEUP_EYESHADOW_02", "light_makeup/eyeshadow/mu_eyeshadow_02.png", R.mipmap.icon_light_makeup_eyeshadow_02, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_03("MAKEUP_EYESHADOW_03", "light_makeup/eyeshadow/mu_eyeshadow_03.png", R.mipmap.icon_light_makeup_eyeshadow_03, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_04("MAKEUP_EYESHADOW_04", "light_makeup/eyeshadow/mu_eyeshadow_04.png", R.mipmap.icon_light_makeup_eyeshadow_04, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_05("MAKEUP_EYESHADOW_05", "light_makeup/eyeshadow/mu_eyeshadow_05.png", R.mipmap.icon_light_makeup_eyeshadow_05, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_06("MAKEUP_EYESHADOW_06", "light_makeup/eyeshadow/mu_eyeshadow_06.png", R.mipmap.icon_light_makeup_eyeshadow_06, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_07("MAKEUP_EYESHADOW_07", "light_makeup/eyeshadow/mu_eyeshadow_07.png", R.mipmap.icon_light_makeup_eyeshadow_07, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_08("MAKEUP_EYESHADOW_08", "light_makeup/eyeshadow/mu_eyeshadow_08.png", R.mipmap.icon_light_makeup_eyeshadow_08, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_09("MAKEUP_EYESHADOW_09", "light_makeup/eyeshadow/mu_eyeshadow_09.png", R.mipmap.icon_light_makeup_eyeshadow_09, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_10("MAKEUP_EYESHADOW_10", "light_makeup/eyeshadow/mu_eyeshadow_10.png", R.mipmap.icon_light_makeup_eyeshadow_10, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_11("MAKEUP_EYESHADOW_11", "light_makeup/eyeshadow/mu_eyeshadow_11.png", R.mipmap.icon_light_makeup_eyeshadow_11, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_12("MAKEUP_EYESHADOW_12", "light_makeup/eyeshadow/mu_eyeshadow_12.png", R.mipmap.icon_light_makeup_eyeshadow_12, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_13("MAKEUP_EYESHADOW_13", "light_makeup/eyeshadow/mu_eyeshadow_13.png", R.mipmap.icon_light_makeup_eyeshadow_13, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_14("MAKEUP_EYESHADOW_14", "light_makeup/eyeshadow/mu_eyeshadow_14.png", R.mipmap.icon_light_makeup_eyeshadow_14, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_15("MAKEUP_EYESHADOW_15", "light_makeup/eyeshadow/mu_eyeshadow_15.png", R.mipmap.icon_light_makeup_eyeshadow_15, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_16("MAKEUP_EYESHADOW_16", "light_makeup/eyeshadow/mu_eyeshadow_16.png", R.mipmap.icon_light_makeup_eyeshadow_16, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_17("MAKEUP_EYESHADOW_17", "light_makeup/eyeshadow/mu_eyeshadow_17.png", R.mipmap.icon_light_makeup_eyeshadow_17, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_18("MAKEUP_EYESHADOW_18", "light_makeup/eyeshadow/mu_eyeshadow_18.png", R.mipmap.icon_light_makeup_eyeshadow_18, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_19("MAKEUP_EYESHADOW_19", "light_makeup/eyeshadow/mu_eyeshadow_19.png", R.mipmap.icon_light_makeup_eyeshadow_19, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_20("MAKEUP_EYESHADOW_20", "light_makeup/eyeshadow/mu_eyeshadow_20.png", R.mipmap.icon_light_makeup_eyeshadow_20, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_21("MAKEUP_EYESHADOW_21", "light_makeup/eyeshadow/mu_eyeshadow_21.png", R.mipmap.icon_light_makeup_eyeshadow_21, R.string.makeup_radio_eye_shadow), + + MAKEUP_EYE_SHADOW_22("MAKEUP_EYESHADOW_22", "light_makeup/eyeshadow/mu_eyeshadow_22.png", R.mipmap.icon_light_makeup_eyeshadow_22, R.string.makeup_radio_eye_shadow), + + // 口红 + MAKEUP_LIPSTICK_01("MAKEUP_LIPSTICK_01", "light_makeup/lipstick/mu_lip_01.json", R.mipmap.icon_light_makeup_lip_01, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_02("MAKEUP_LIPSTICK_02", "light_makeup/lipstick/mu_lip_02.json", R.mipmap.icon_light_makeup_lip_02, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_03("MAKEUP_LIPSTICK_03", "light_makeup/lipstick/mu_lip_03.json", R.mipmap.icon_light_makeup_lip_03, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_10("MAKEUP_LIPSTICK_10", "light_makeup/lipstick/mu_lip_10.json", R.mipmap.icon_light_makeup_lip_10, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_11("MAKEUP_LIPSTICK_11", "light_makeup/lipstick/mu_lip_11.json", R.mipmap.icon_light_makeup_lip_12, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_12("MAKEUP_LIPSTICK_12", "light_makeup/lipstick/mu_lip_12.json", R.mipmap.icon_light_makeup_lip_12, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_13("MAKEUP_LIPSTICK_13", "light_makeup/lipstick/mu_lip_13.json", R.mipmap.icon_light_makeup_lip_13, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_14("MAKEUP_LIPSTICK_14", "light_makeup/lipstick/mu_lip_14.json", R.mipmap.icon_light_makeup_lip_14, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_15("MAKEUP_LIPSTICK_15", "light_makeup/lipstick/mu_lip_15.json", R.mipmap.icon_light_makeup_lip_15, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_16("MAKEUP_LIPSTICK_16", "light_makeup/lipstick/mu_lip_16.json", R.mipmap.icon_light_makeup_lip_16, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_17("MAKEUP_LIPSTICK_17", "light_makeup/lipstick/mu_lip_17.json", R.mipmap.icon_light_makeup_lip_17, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_18("MAKEUP_LIPSTICK_18", "light_makeup/lipstick/mu_lip_18.json", R.mipmap.icon_light_makeup_lip_18, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_19("MAKEUP_LIPSTICK_19", "light_makeup/lipstick/mu_lip_19.json", R.mipmap.icon_light_makeup_lip_19, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_20("MAKEUP_LIPSTICK_20", "light_makeup/lipstick/mu_lip_20.json", R.mipmap.icon_light_makeup_lip_20, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_21("MAKEUP_LIPSTICK_21", "light_makeup/lipstick/mu_lip_21.json", R.mipmap.icon_light_makeup_lip_21, R.string.makeup_radio_lipstick), + + MAKEUP_LIPSTICK_22("MAKEUP_LIPSTICK_22", "light_makeup/lipstick/mu_lip_22.json", R.mipmap.icon_light_makeup_lip_22, R.string.makeup_radio_lipstick); + + + private final String key; + private final String path; + private final int iconRes; + private final int strRes; + + LightMakeUpEnum(String key, String path, int iconRes, int strRes) { + this.key = key; + this.path = path; + this.iconRes = iconRes; + this.strRes = strRes; + } + + /** + * 获取口红颜色 + * + * @return + */ + public FUColorRGBData getLipColorRGBData() { + double[] colorArray = loadRgbaColorFromLocal(FaceUnityData.mApplication, path); + if (colorArray != null && colorArray.length == 4) { + return new FUColorRGBData(colorArray[0] * 255, colorArray[1] * 255, colorArray[2] * 255, colorArray[3] * 255); + } + return new FUColorRGBData(0.0, 0.0, 0.0, 0.0); + } + + } + + //endregion + + /** + * 读取 RGBA 颜色数据 + * + * @param context + * @param path path + * @return + */ + public static double[] loadRgbaColorFromLocal(Context context, String path) { + InputStream inputStream = FileUtils.readInputStreamByPath(context, path); + if (inputStream != null) { + try { + byte[] bytes = new byte[inputStream.available()]; + inputStream.read(bytes); + JSONObject jsonObject = new JSONObject(new String(bytes)); + JSONArray jsonArray = jsonObject.optJSONArray("rgba"); + double[] colorArray = new double[jsonArray.length()]; + for (int i = 0; i < jsonArray.length(); i++) { + colorArray[i] = jsonArray.optDouble(i); + } + return colorArray; + } catch (IOException | JSONException e) { + e.printStackTrace(); + } finally { + try { + inputStream.close(); + } catch (Exception e) { + e.printStackTrace(); + } + } + } + return null; + } + + +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/PortraitSegmentSource.java b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/PortraitSegmentSource.java new file mode 100644 index 000000000..15d15117f --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/PortraitSegmentSource.java @@ -0,0 +1,107 @@ +package com.yunbao.faceunity.repo; + +import static android.content.Context.MODE_PRIVATE; + +import android.content.SharedPreferences; + + +import com.faceunity.core.entity.FUBundleData; +import com.faceunity.core.entity.FUColorRGBData; +import com.faceunity.core.model.prop.humanOutline.HumanOutline; +import com.yunbao.faceunity.R; +import com.yunbao.faceunity.entity.FunctionEnum; +import com.yunbao.faceunity.entity.PropCustomBean; +import com.yunbao.faceunity.infe.AbstractPropCustomDataFactory; +import com.yunbao.faceunity.utils.FaceUnityConfig; +import com.yunbao.faceunity.utils.FaceUnityData; + +import java.io.File; +import java.util.ArrayList; + +/** + * DESC:人像分割数据构造 + * Created on 2021/3/28 + */ +public class PortraitSegmentSource { + + private static final String BG_SEG_CUSTOM_FILEPATH = "bg_seg_custom"; + + /** + * 缓存自定义添加人像 + * + * @param path + */ + public static void saveCachePortraitSegment(String path) { + SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(BG_SEG_CUSTOM_FILEPATH, MODE_PRIVATE); + sp.edit().putString(BG_SEG_CUSTOM_FILEPATH, path).apply(); + } + + /** + * 获取自定义添加人像 + * + * @return + */ + public static String getCachePortraitSegment() { + SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(BG_SEG_CUSTOM_FILEPATH, MODE_PRIVATE); + return sp.getString(BG_SEG_CUSTOM_FILEPATH, ""); + } + + + /** + * 构造道具队列 + * + * @return + */ + public static ArrayList buildPropBeans() { + ArrayList propBeans = new ArrayList<>(); + propBeans.add(new PropCustomBean(R.mipmap.icon_control_delete_all, null, AbstractPropCustomDataFactory.TYPE_NONE)); + propBeans.add(new PropCustomBean(R.mipmap.icon_control_add, null, AbstractPropCustomDataFactory.TYPE_ADD)); + PropCustomBean customBean = buildPropCustomBean(getCachePortraitSegment()); + if (customBean != null) { + propBeans.add(customBean); + } + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_human_outline, "effect/segment/human_outline.bundle", FunctionEnum.HUMAN_OUTLINE)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_boyfriend_1, "effect/segment/boyfriend1.bundle", FunctionEnum.PORTRAIT_SEGMENT)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_boyfriend_2, "effect/segment/boyfriend3.bundle", FunctionEnum.PORTRAIT_SEGMENT)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_boyfriend_3, "effect/segment/boyfriend2.bundle", FunctionEnum.PORTRAIT_SEGMENT)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_hez_ztt_fu, "effect/segment/hez_ztt_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT, R.string.hez_ztt_fu)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_gufeng_zh_fu, "effect/segment/gufeng_zh_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_xiandai_ztt_fu, "effect/segment/xiandai_ztt_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_sea_lm_fu, "effect/segment/sea_lm_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT)); + propBeans.add(new PropCustomBean(R.mipmap.icon_segment_ice_lm_fu, "effect/segment/ice_lm_fu.bundle", FunctionEnum.PORTRAIT_SEGMENT)); + return propBeans; + } + + + /** + * 构造自定义人像分割 + * + * @param path + * @return + */ + public static PropCustomBean buildPropCustomBean(String path) { + if (path != null && path.trim().length() > 0 && new File(path).exists()) { + saveCachePortraitSegment(path); + return new PropCustomBean(0, FaceUnityConfig.BUNDLE_BG_SEG_CUSTOM, FunctionEnum.BG_SEG_CUSTOM, 0, path ); + } + return null; + + } + + + /** + * 构造人像分割线模型 + * + * @param path + * @return + */ + public static HumanOutline getHumanOutline(String path) { + HumanOutline humanOutline = new HumanOutline(new FUBundleData(path)); + humanOutline.setLineSize(2.8); + humanOutline.setLineGap(2.8); + humanOutline.setLineColor(new FUColorRGBData(255.0, 196.0, 0.0)); + return humanOutline; + } + + +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/PropSource.java b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/PropSource.java index b832747af..1d9534f91 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/repo/PropSource.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/repo/PropSource.java @@ -1,28 +1,79 @@ package com.yunbao.faceunity.repo; - import com.yunbao.faceunity.R; +import com.yunbao.faceunity.entity.FunctionEnum; import com.yunbao.faceunity.entity.PropBean; import java.util.ArrayList; - /** - * DESC:道具数据构造 + * DESC:道具数据构造:道具贴图、AR面具、搞笑大头、表情识别、哈哈镜、手势识别、游戏 * Created on 2021/3/28 */ public class PropSource { - /** - * 构造贴纸列表 - * - * @return - */ - public static ArrayList buildPropBeans() { + public static ArrayList buildPropBeans(int propType) { ArrayList propBeans = new ArrayList<>(); - propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null)); - propBeans.add(new PropBean(R.mipmap.icon_sticker_sdlu, "sticker/sdlu.bundle")); - propBeans.add(new PropBean(R.mipmap.icon_sticker_fashi, "sticker/fashi.bundle")); + switch (propType) { + case FunctionEnum.STICKER: + propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null)); + propBeans.add(new PropBean(R.mipmap.icon_sticker_cat_sparks, "effect/normal/cat_sparks.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_sticker_fu_zh_fenshu, "effect/normal/fu_zh_fenshu.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_sticker_sdlr, "effect/normal/sdlr.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_sticker_xlong_zh_fu, "effect/normal/xlong_zh_fu.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_sticker_newy1, "effect/normal/newy1.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_sticker_redribbt, "effect/normal/redribbt.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_sticker_daisypig, "effect/normal/daisypig.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_sticker_sdlu, "effect/normal/sdlu.bundle")); + break; + case FunctionEnum.AR_MASK: + propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null)); + propBeans.add(new PropBean(R.mipmap.icon_ar_bluebird, "effect/ar/bluebird.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_ar_lanhudie, "effect/ar/lanhudie.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_ar_fenhudie, "effect/ar/fenhudie.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_ar_tiger_huang, "effect/ar/tiger_huang.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_ar_tiger_bai, "effect/ar/tiger_bai.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_ar_baozi, "effect/ar/baozi.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_ar_tiger, "effect/ar/tiger.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_ar_xiongmao, "effect/ar/xiongmao.bundle")); + break; + case FunctionEnum.BIG_HEAD: + propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null)); + propBeans.add(new PropBean(R.mipmap.icon_big_head, "effect/big_head/big_head.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_big_head_husky_face, "effect/big_head/big_head_facewarp2.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_big_head_sausage_mouth, "effect/big_head/big_head_facewarp4.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_big_head_blush, "effect/big_head/big_head_facewarp5.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_big_head_dark_circles, "effect/big_head/big_head_facewarp6.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_big_head_smiling_head, "effect/big_head/big_head_smile.bundle", R.string.xiaobianzi_zh_fu)); + break; + case FunctionEnum.EXPRESSION_RECOGNITION: + propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null)); + propBeans.add(new PropBean(R.mipmap.icon_expression_future_warrior, "effect/expression/future_warrior.bundle", R.string.future_warrior)); + propBeans.add(new PropBean(R.mipmap.icon_expression_jet_mask, "effect/expression/jet_mask.bundle", R.string.jet_mask)); + propBeans.add(new PropBean(R.mipmap.icon_expression_sdx2, "effect/expression/sdx2.bundle", R.string.sdx2)); + propBeans.add(new PropBean(R.mipmap.icon_expression_luhantongkuan_ztt_fu, "effect/expression/luhantongkuan_ztt_fu.bundle", R.string.luhantongkuan_ztt_fu)); + propBeans.add(new PropBean(R.mipmap.icon_expression_qingqing_ztt_fu, "effect/expression/qingqing_ztt_fu.bundle", R.string.qingqing_ztt_fu)); + propBeans.add(new PropBean(R.mipmap.icon_expression_xiaobianzi_zh_fu, "effect/expression/xiaobianzi_zh_fu.bundle", R.string.xiaobianzi_zh_fu)); + propBeans.add(new PropBean(R.mipmap.icon_expression_xiaoxueshen_ztt_fu, "effect/expression/xiaoxueshen_ztt_fu.bundle", R.string.xiaoxueshen_ztt_fu)); + break; + case FunctionEnum.FACE_WARP: + propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null)); + propBeans.add(new PropBean(R.mipmap.icon_face_warp_2, "effect/facewarp/facewarp2.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_face_warp_3, "effect/facewarp/facewarp3.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_face_warp_4, "effect/facewarp/facewarp4.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_face_warp_5, "effect/facewarp/facewarp5.bundle")); + propBeans.add(new PropBean(R.mipmap.icon_face_warp_6, "effect/facewarp/facewarp6.bundle")); + break; + case FunctionEnum.GESTURE_RECOGNITION: + propBeans.add(new PropBean(R.mipmap.icon_control_delete_all, null)); + propBeans.add(new PropBean(R.mipmap.icon_gesture_rain, "effect/gesture/ctrl_rain.bundle", R.string.push_hand)); + propBeans.add(new PropBean(R.mipmap.icon_gesture_snow, "effect/gesture/ctrl_snow.bundle", R.string.push_hand)); + propBeans.add(new PropBean(R.mipmap.icon_gesture_flower, "effect/gesture/ctrl_flower.bundle", R.string.push_hand)); + propBeans.add(new PropBean(R.mipmap.icon_gesture_koreaheart, "effect/gesture/ssd_thread_korheart.bundle", R.string.fu_lm_koreaheart)); + propBeans.add(new PropBean(R.mipmap.icon_gesture_six, "effect/gesture/ssd_thread_six.bundle", R.string.ssd_thread_six)); + propBeans.add(new PropBean(R.mipmap.icon_gesture_cute, "effect/gesture/ssd_thread_cute.bundle", R.string.ssd_thread_cute)); + break; + } return propBeans; } } diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/ui/FaceUnityView.java b/FaceUnity/src/main/java/com/yunbao/faceunity/ui/FaceUnityView.java index c106387f3..bd231a4dc 100644 --- a/FaceUnity/src/main/java/com/yunbao/faceunity/ui/FaceUnityView.java +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/ui/FaceUnityView.java @@ -7,6 +7,8 @@ import android.view.View; import android.widget.LinearLayout; import androidx.annotation.Nullable; +import androidx.recyclerview.widget.GridLayoutManager; +import androidx.recyclerview.widget.RecyclerView; import com.yunbao.faceunity.R; @@ -17,6 +19,9 @@ import com.yunbao.faceunity.control.MakeupControlView; import com.yunbao.faceunity.control.PropControlView; import com.yunbao.faceunity.data.FaceUnityDataFactory; +import java.util.HashMap; +import java.util.Map; + /** * DESC: * Created on 2021/4/26 @@ -24,6 +29,7 @@ import com.yunbao.faceunity.data.FaceUnityDataFactory; public class FaceUnityView extends LinearLayout { private Context mContext; + private RecyclerView menuGroup; public FaceUnityView(Context context) { super(context); @@ -67,36 +73,15 @@ public class FaceUnityView extends LinearLayout { */ public void bindDataFactory(FaceUnityDataFactory dataFactory) { mDataFactory = dataFactory; - mFaceBeautyControlView.bindDataFactory(dataFactory.mFaceBeautyDataFactory); - mMakeupControlView.bindDataFactory(dataFactory.mMakeupDataFactory); - mPropControlView.bindDataFactory(dataFactory.mPropDataFactory); - mBodyBeautyControlView.bindDataFactory(dataFactory.mBodyBeautyDataFactory); - switch (dataFactory.currentFunctionIndex) { - case 0: - mCheckGroupView.check(R.id.radio_beauty); - break; - case 1: - mCheckGroupView.check(R.id.radio_sticker); - break; - case 2: - mCheckGroupView.check(R.id.radio_makeup); - break; - case 3: - mCheckGroupView.check(R.id.radio_body); - break; - } + } /** * 初始化View */ private void initView() { - mCheckGroupView = findViewById(R.id.group_function); - mFaceBeautyControlView = findViewById(R.id.control_beauty); - mMakeupControlView = findViewById(R.id.control_makeup); - mPropControlView = findViewById(R.id.control_prop); - mBodyBeautyControlView = findViewById(R.id.control_body); - lineView = findViewById(R.id.line); + menuGroup=findViewById(R.id.menu_group); + initMenuGroup(); } @@ -104,23 +89,7 @@ public class FaceUnityView extends LinearLayout { * 底部功能菜单切换 */ private void bindBottomView() { - mCheckGroupView.setOnCheckedChangeListener((group, checkedId) -> { - if (checkedId == R.id.radio_beauty) { - showFunction(0); - mDataFactory.onFunctionSelected(0); - } else if (checkedId == R.id.radio_sticker) { - showFunction(1); - mDataFactory.onFunctionSelected(1); - } else if (checkedId == R.id.radio_makeup) { - showFunction(2); - mDataFactory.onFunctionSelected(2); - } else if (checkedId == R.id.radio_body) { - showFunction(3); - mDataFactory.onFunctionSelected(3); - } else { - showFunction(-1); - } - }); + } /** @@ -129,12 +98,19 @@ public class FaceUnityView extends LinearLayout { * @param index Int */ private void showFunction(int index) { - mFaceBeautyControlView.setVisibility((index == 0) ? View.VISIBLE : View.GONE); - mPropControlView.setVisibility((index == 1) ? View.VISIBLE : View.GONE); - mMakeupControlView.setVisibility((index == 2) ? View.VISIBLE : View.GONE); - mBodyBeautyControlView.setVisibility((index == 3) ? View.VISIBLE : View.GONE); - lineView.setVisibility((index != -1) ? View.VISIBLE : View.GONE); + + } + private void initMenuGroup(){ + menuGroup.setLayoutManager(new GridLayoutManager(mContext,4)); + Map layoutItem=new HashMap<>(); + layoutItem.put(R.string.home_function_name_beauty,R.mipmap.ico_home_beauty); + layoutItem.put(R.string.home_function_name_makeup,R.mipmap.ico_home_makeup); + layoutItem.put(R.string.home_function_name_beauty_body,R.mipmap.ico_home_beauty_body); + layoutItem.put(R.string.home_function_name_beauty_body,R.mipmap.ico_home_beauty_body); + layoutItem.put(R.string.home_function_name_big_head,R.mipmap.ico_home_big_head); + layoutItem.put(R.string.home_function_name_animoji,R.mipmap.ico_home_animoji); + layoutItem.put(R.string.home_function_name_sticker,R.mipmap.ico_home_sticker); + layoutItem.put(R.string.home_function_name_fine_sticker,R.mipmap.ico_home_fine_sticker); } - } diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/ui/fragments/FaceContainerFragment.java b/FaceUnity/src/main/java/com/yunbao/faceunity/ui/fragments/FaceContainerFragment.java new file mode 100644 index 000000000..41057b053 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/ui/fragments/FaceContainerFragment.java @@ -0,0 +1,17 @@ +package com.yunbao.faceunity.ui.fragments; + +import android.view.LayoutInflater; +import android.view.View; +import android.view.ViewGroup; +import android.widget.LinearLayout; + +import androidx.annotation.Nullable; + +import com.yunbao.faceunity.dialog.BaseDialogFragment; + +public class FaceContainerFragment extends BaseDialogFragment { + @Override + protected View createDialogView(LayoutInflater inflater, @Nullable ViewGroup container) { + return new LinearLayout(inflater.getContext()); + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FUUtils.java b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FUUtils.java new file mode 100644 index 000000000..2194ea131 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FUUtils.java @@ -0,0 +1,271 @@ +package com.yunbao.faceunity.utils; + +import android.content.Context; +import android.content.SharedPreferences; + +import com.faceunity.core.model.facebeauty.FaceBeauty; +import com.google.gson.Gson; +import com.yunbao.faceunity.data.FaceBeautyData; +import com.yunbao.faceunity.entity.FaceBeautyFilterBean; + +import java.util.ArrayList; + +/** + * 将FaceBeauty FaceBeautyData 互相设置 + */ +public class FUUtils { + private static final String SP_NAME = "FaceBeauty"; + private static final String SP_KEY_NAME = "faceBeautyData"; + + /** + * 将FaceBeauty 转 FaceBeautyData + * + * @param faceBeautyData + */ + public static void buildFaceBeautyData(FaceBeautyData faceBeautyData, FaceBeauty faceBeauty, ArrayList filterList, int styleTypeIndex) { + if (faceBeauty != null) { + /* 美肤 */ + /* 磨皮类型 */ + faceBeautyData.blurType = faceBeauty.getBlurType(); + /* 磨皮程度 */ + faceBeautyData.blurIntensity = faceBeauty.getBlurIntensity(); + /* 美白程度 */ + faceBeautyData.colorIntensity = faceBeauty.getColorIntensity(); + /* 红润程度 */ + faceBeautyData.redIntensity = faceBeauty.getRedIntensity(); + /* 锐化程度 */ + faceBeautyData.sharpenIntensity = faceBeauty.getSharpenIntensity(); + /* 亮眼程度 */ + faceBeautyData.eyeBrightIntensity = faceBeauty.getEyeBrightIntensity(); + /* 美牙程度 */ + faceBeautyData.toothIntensity = faceBeauty.getToothIntensity(); + /* 去黑眼圈强度*/ + faceBeautyData.removePouchIntensity = faceBeauty.getRemovePouchIntensity(); + /* 去法令纹强度*/ + faceBeautyData.removeLawPatternIntensity = faceBeauty.getRemoveLawPatternIntensity(); + + /* 美型 */ + /* 瘦脸程度 */ + faceBeautyData.cheekThinningIntensity = faceBeauty.getCheekThinningIntensity(); + /* V脸程度 */ + faceBeautyData.cheekVIntensity = faceBeauty.getCheekVIntensity(); + /* 窄脸程度 */ + faceBeautyData.cheekNarrowIntensity = faceBeauty.getCheekNarrowIntensity(); + /* 短脸程度 */ + faceBeautyData.cheekShortIntensity = faceBeauty.getCheekShortIntensity(); + /* 小脸程度 */ + faceBeautyData.cheekSmallIntensity = faceBeauty.getCheekSmallIntensity(); + /* 瘦颧骨 */ + faceBeautyData.cheekBonesIntensity = faceBeauty.getCheekBonesIntensity(); + /* 瘦下颌骨 */ + faceBeautyData.lowerJawIntensity = faceBeauty.getLowerJawIntensity(); + /* 大眼程度 */ + faceBeautyData.eyeEnlargingIntensity = faceBeauty.getEyeEnlargingIntensity(); + /* 圆眼程度 */ + faceBeautyData.eyeCircleIntensity = faceBeauty.getEyeCircleIntensity(); + /* 下巴调整程度 */ + faceBeautyData.chinIntensity = faceBeauty.getChinIntensity(); + /* 额头调整程度 */ + faceBeautyData.forHeadIntensity = faceBeauty.getForHeadIntensity(); + /* 瘦鼻程度 */ + faceBeautyData.noseIntensity = faceBeauty.getNoseIntensity(); + /* 嘴巴调整程度 */ + faceBeautyData.mouthIntensity = faceBeauty.getMouthIntensity(); + /* 开眼角强度 */ + faceBeautyData.canthusIntensity = faceBeauty.getCanthusIntensity(); + /* 眼睛间距 */ + faceBeautyData.eyeSpaceIntensity = faceBeauty.getEyeSpaceIntensity(); + /* 眼睛角度 */ + faceBeautyData.eyeRotateIntensity = faceBeauty.getEyeRotateIntensity(); + /* 鼻子长度 */ + faceBeautyData.longNoseIntensity = faceBeauty.getLongNoseIntensity(); + /* 调节人中 */ + faceBeautyData.philtrumIntensity = faceBeauty.getPhiltrumIntensity(); + /* 微笑嘴角强度 */ + faceBeautyData.smileIntensity = faceBeauty.getSmileIntensity(); + /* 眉毛上下 */ + faceBeautyData.browHeightIntensity = faceBeauty.getBrowHeightIntensity(); + /* 眉毛间距 */ + faceBeautyData.browSpaceIntensity = faceBeauty.getBrowSpaceIntensity(); + + /* 滤镜相关 */ + if (filterList != null) { + for (FaceBeautyFilterBean filterBean:filterList) { + faceBeautyData.filterMap.put(filterBean.getKey(),filterBean.getIntensity()); + } + } + /* 滤镜名称 */ + faceBeautyData.filterName = faceBeauty.getFilterName(); + /* 滤镜强度 */ + faceBeautyData.filterIntensity = faceBeauty.getFilterIntensity(); + + /* 是否开启风格 */ + faceBeautyData.styleTypeIndex = styleTypeIndex; + } + } + + /** + * 将FaceBeauty 转 FaceBeautyData + * + * @param faceBeautyData + */ + public static boolean setFaceBeauty(FaceBeautyData faceBeautyData ,FaceBeauty faceBeauty) { + if (faceBeautyData == null) { + return false; + } + if (faceBeauty != null) { + /* 如果用户开启了风格推荐 */ + //下面是否则 + /* 美肤 */ + /* 磨皮类型 */ + if (faceBeautyData.blurType != faceBeauty.getBlurType()) + faceBeauty.setBlurType(faceBeautyData.blurType); + /* 磨皮程度 */ + if (faceBeautyData.blurIntensity != faceBeauty.getBlurIntensity()) + faceBeauty.setBlurIntensity(faceBeautyData.blurIntensity); + /* 美白程度 */ + if (faceBeautyData.colorIntensity != faceBeauty.getColorIntensity()) + faceBeauty.setColorIntensity(faceBeautyData.colorIntensity); + /* 红润程度 */ + if (faceBeautyData.redIntensity != faceBeauty.getRedIntensity()) + faceBeauty.setRedIntensity(faceBeautyData.redIntensity); + /* 锐化程度 */ + if (faceBeautyData.sharpenIntensity != faceBeauty.getSharpenIntensity()) + faceBeauty.setSharpenIntensity(faceBeautyData.sharpenIntensity); + /* 亮眼程度 */ + if (faceBeautyData.eyeBrightIntensity != faceBeauty.getEyeBrightIntensity()) + faceBeauty.setEyeBrightIntensity(faceBeautyData.eyeBrightIntensity); + /* 美牙程度 */ + if (faceBeautyData.toothIntensity != faceBeauty.getToothIntensity()) + faceBeauty.setToothIntensity(faceBeautyData.toothIntensity); + /* 去黑眼圈强度*/ + if (faceBeautyData.removePouchIntensity != faceBeauty.getRemovePouchIntensity()) + faceBeauty.setRemovePouchIntensity(faceBeautyData.removePouchIntensity); + /* 去法令纹强度*/ + if (faceBeautyData.removeLawPatternIntensity != faceBeauty.getRemoveLawPatternIntensity()) + faceBeauty.setRemoveLawPatternIntensity(faceBeautyData.removeLawPatternIntensity); + + /* 美型 */ + /* 瘦脸程度 */ + if (faceBeautyData.cheekThinningIntensity != faceBeauty.getCheekThinningIntensity()) + faceBeauty.setCheekThinningIntensity(faceBeautyData.cheekThinningIntensity); + /* V脸程度 */ + if (faceBeautyData.cheekVIntensity != faceBeauty.getCheekVIntensity()) + faceBeauty.setCheekVIntensity(faceBeautyData.cheekVIntensity); + /* 窄脸程度 */ + /* V脸程度 */ + if (faceBeautyData.cheekNarrowIntensity != faceBeauty.getCheekNarrowIntensity()) + faceBeauty.setCheekNarrowIntensity(faceBeautyData.cheekNarrowIntensity); + /* 短脸程度 */ + if (faceBeautyData.cheekShortIntensity != faceBeauty.getCheekShortIntensity()) + faceBeauty.setCheekShortIntensity(faceBeautyData.cheekShortIntensity); + /* 小脸程度 */ + if (faceBeautyData.cheekSmallIntensity != faceBeauty.getCheekSmallIntensity()) + faceBeauty.setCheekSmallIntensity(faceBeautyData.cheekSmallIntensity); + /* 瘦颧骨 */ + if (faceBeautyData.cheekBonesIntensity != faceBeauty.getCheekBonesIntensity()) + faceBeauty.setCheekBonesIntensity(faceBeautyData.cheekBonesIntensity); + /* 瘦下颌骨 */ + if (faceBeautyData.lowerJawIntensity != faceBeauty.getLowerJawIntensity()) + faceBeauty.setLowerJawIntensity(faceBeautyData.lowerJawIntensity); + /* 大眼程度 */ + if (faceBeautyData.eyeEnlargingIntensity != faceBeauty.getEyeEnlargingIntensity()) + faceBeauty.setEyeEnlargingIntensity(faceBeautyData.eyeEnlargingIntensity); + /* 圆眼程度 */ + if (faceBeautyData.eyeCircleIntensity != faceBeauty.getEyeCircleIntensity()) + faceBeauty.setEyeCircleIntensity(faceBeautyData.eyeCircleIntensity); + /* 下巴调整程度 */ + if (faceBeautyData.chinIntensity != faceBeauty.getChinIntensity()) + faceBeauty.setChinIntensity(faceBeautyData.chinIntensity); + /* 额头调整程度 */ + if (faceBeautyData.forHeadIntensity != faceBeauty.getForHeadIntensity()) + faceBeauty.setForHeadIntensity(faceBeautyData.forHeadIntensity); + /* 瘦鼻程度 */ + if (faceBeautyData.noseIntensity != faceBeauty.getNoseIntensity()) + faceBeauty.setNoseIntensity(faceBeautyData.noseIntensity); + /* 嘴巴调整程度 */ + if (faceBeautyData.mouthIntensity != faceBeauty.getMouthIntensity()) + faceBeauty.setMouthIntensity(faceBeautyData.mouthIntensity); + /* 开眼角强度 */ + if (faceBeautyData.canthusIntensity != faceBeauty.getCanthusIntensity()) + faceBeauty.setCanthusIntensity(faceBeautyData.canthusIntensity); + /* 眼睛间距 */ + if (faceBeautyData.eyeSpaceIntensity != faceBeauty.getEyeSpaceIntensity()) + faceBeauty.setEyeSpaceIntensity(faceBeautyData.eyeSpaceIntensity); + /* 眼睛角度 */ + if (faceBeautyData.eyeRotateIntensity != faceBeauty.getEyeRotateIntensity()) + faceBeauty.setEyeRotateIntensity(faceBeautyData.eyeRotateIntensity); + /* 鼻子长度 */ + if (faceBeautyData.longNoseIntensity != faceBeauty.getLongNoseIntensity()) + faceBeauty.setLongNoseIntensity(faceBeautyData.longNoseIntensity); + /* 调节人中 */ + if (faceBeautyData.philtrumIntensity != faceBeauty.getPhiltrumIntensity()) + faceBeauty.setPhiltrumIntensity(faceBeautyData.philtrumIntensity); + /* 微笑嘴角强度 */ + if (faceBeautyData.smileIntensity != faceBeauty.getSmileIntensity()) + faceBeauty.setSmileIntensity(faceBeautyData.smileIntensity); + /* 眉毛上下 */ + if (faceBeautyData.browHeightIntensity != faceBeauty.getBrowHeightIntensity()) + faceBeauty.setBrowHeightIntensity(faceBeautyData.browHeightIntensity); + /* 眉毛间距 */ + if (faceBeautyData.browSpaceIntensity != faceBeauty.getBrowSpaceIntensity()) + faceBeauty.setBrowSpaceIntensity(faceBeautyData.browSpaceIntensity); + + /* 滤镜相关 */ + /* 滤镜名称 */ + if (!faceBeautyData.filterName.equals(faceBeauty.getFilterName())) + faceBeauty.setFilterName(faceBeautyData.filterName); + if (faceBeautyData.filterIntensity != faceBeauty.getFilterIntensity()) + faceBeauty.setFilterIntensity(faceBeautyData.filterIntensity); + return true; + } + + return false; + } + + /** + * 将FaceBeautyData保存到文件 + * + * @param faceBeautyData + */ + public static void saveFaceBeautyData2File(FaceBeautyData faceBeautyData, FaceBeauty faceBeauty, ArrayList filterList, int styleTypeIndex) { + buildFaceBeautyData(faceBeautyData,faceBeauty,filterList,styleTypeIndex); + saveFaceBeautyData2File(faceBeautyData); + } + + /** + * 将FaceBeautyData保存到文件 + * + * @param faceBeautyData + */ + public static void saveFaceBeautyData2File(FaceBeautyData faceBeautyData) { + Gson gson = new Gson(); + String faceBeautyString = gson.toJson(faceBeautyData); + saveToSp(SP_KEY_NAME, faceBeautyString); + } + + /** + * 获取bean对象 + * + * @return + */ + public static FaceBeautyData loadFaceBeautyData() { + String faceBeautyData = loadFormSp(SP_KEY_NAME); + if (faceBeautyData != null && !faceBeautyData.isEmpty()) { + Gson gson = new Gson(); + FaceBeautyData faceBeautyDataBean = gson.fromJson(faceBeautyData, FaceBeautyData.class); + return faceBeautyDataBean; + } + return null; + } + + private static void saveToSp(String key, String value) { + SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); + sp.edit().putString(key, value).apply(); + } + + private static String loadFormSp(String key) { + SharedPreferences sp = FaceUnityData.mApplication.getSharedPreferences(SP_NAME, Context.MODE_PRIVATE); + return sp.getString(key, ""); + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FaceUnityData.java b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FaceUnityData.java new file mode 100644 index 000000000..bb9cc8a03 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FaceUnityData.java @@ -0,0 +1,7 @@ +package com.yunbao.faceunity.utils; + +import android.content.Context; + +public class FaceUnityData { + public static Context mApplication; +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FileUtils.java b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FileUtils.java new file mode 100644 index 000000000..3e31b5564 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/FileUtils.java @@ -0,0 +1,580 @@ +package com.yunbao.faceunity.utils; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.database.Cursor; +import android.graphics.Bitmap; +import android.graphics.BitmapFactory; +import android.graphics.ImageFormat; +import android.graphics.Matrix; +import android.graphics.Rect; +import android.graphics.YuvImage; +import android.media.ExifInterface; +import android.media.MediaMetadataRetriever; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.MediaStore; + +import java.io.BufferedInputStream; +import java.io.BufferedOutputStream; +import java.io.ByteArrayOutputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.text.SimpleDateFormat; +import java.util.ArrayList; +import java.util.GregorianCalendar; +import java.util.Locale; +import java.util.regex.Pattern; + +/** + * DESC: + * Created on 2021/3/12 + */ +public class FileUtils { + public static final String DCIM_FILE_PATH = Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DCIM).getPath(); + public static final String photoFilePath; + public static final String videoFilePath; + public static final String exportVideoDir; + + static { + if (Build.FINGERPRINT.contains("Flyme") + || Pattern.compile("Flyme", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find() + || Build.MANUFACTURER.contains("Meizu") + || Build.MANUFACTURER.contains("MeiZu")) { + photoFilePath = DCIM_FILE_PATH + File.separator + "Camera" + File.separator; + videoFilePath = DCIM_FILE_PATH + File.separator + "Video" + File.separator; + } else if (Build.FINGERPRINT.contains("vivo") + || Pattern.compile("vivo", Pattern.CASE_INSENSITIVE).matcher(Build.DISPLAY).find() + || Build.MANUFACTURER.contains("vivo") + || Build.MANUFACTURER.contains("Vivo")) { + photoFilePath = videoFilePath = Environment.getExternalStoragePublicDirectory("") + File.separator + "相机" + File.separator; + } else { + photoFilePath = videoFilePath = DCIM_FILE_PATH + File.separator + "Camera" + File.separator; + } + exportVideoDir = DCIM_FILE_PATH + File.separator + "FaceUnity" + File.separator; + createFileDir(photoFilePath); + createFileDir(videoFilePath); + createFileDir(exportVideoDir); + } + + public static final String IMAGE_FORMAT_JPG = ".jpg"; + public static final String IMAGE_FORMAT_JPEG = ".jpeg"; + public static final String IMAGE_FORMAT_PNG = ".png"; + public static final String VIDEO_FORMAT_MP4 = ".mp4"; + + + /** + * 创建文件夹 + * + * @param path + */ + public static void createFileDir(String path) { + File dir = new File(path); + if (!dir.exists()) { + dir.mkdirs(); + } + } + + /** + * 应用外部文件目录 + * + * @return + */ + public static File getExternalFileDir(Context context) { + File fileDir = context.getExternalFilesDir(null); + if (fileDir == null) { + fileDir = context.getFilesDir(); + } + return fileDir; + } + + /** + * 应用下缓存文件目录 + * + * @return + */ + public static File getCacheFileDir(Context context) { + File fileDir = context.getCacheDir(); + if (fileDir == null) { + fileDir = context.getFilesDir(); + } + return fileDir; + } + + /** + * 获取当前时间日期 + * + * @return + */ + public static String getDateTimeString() { + GregorianCalendar now = new GregorianCalendar(); + return new SimpleDateFormat("yyyyMMdd-HHmmss", Locale.US).format(now.getTime()); + } + + + /** + * 获取视频缓存文件 + * + * @param context Context + * @return File + */ + public static File getCacheVideoFile(Context context) { + File fileDir = new File(getExternalFileDir(context).getPath() + File.separator + "video"); + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + File file = new File(fileDir, getCurrentVideoFileName()); + if (file.exists()) { + file.delete(); + } + return file; + } + + /** + * 构造视频文件名称 + * + * @return + */ + public static String getCurrentVideoFileName() { + return getDateTimeString() + VIDEO_FORMAT_MP4; + } + + + /** + * 构造图片文件名称 + * + * @return + */ + public static String getCurrentPhotoFileName() { + return getDateTimeString() + IMAGE_FORMAT_JPG; + } + + + /** + * Bitmap保存到本地 + * + * @param context Context + * @param bitmap Bitmap + * @return String? + */ + public static String addBitmapToExternal(Context context, Bitmap bitmap) { + if (bitmap == null) return null; + File fileDir = new File(getExternalFileDir(context).getPath() + File.separator + "photo"); + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + File file = new File(fileDir, getCurrentPhotoFileName()); + if (file.exists()) { + file.delete(); + } + try { + FileOutputStream fos = new FileOutputStream(file); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); + fos.flush(); + fos.close(); + return file.getAbsolutePath(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 将Bitmap文件保存到相册 + * + * @param bitmap Bitmap + */ + public static String addBitmapToAlbum(Context context, Bitmap bitmap) { + if (bitmap == null) return null; + FileOutputStream fos = null; + File dcimFile; + + File fileDir = new File(exportVideoDir); + if (fileDir.exists()) { + dcimFile = new File(exportVideoDir, getCurrentPhotoFileName()); + } else { + dcimFile = new File(photoFilePath, getCurrentPhotoFileName()); + } + if (dcimFile.exists()) { + dcimFile.delete(); + } + try { + fos = new FileOutputStream(dcimFile); + bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos); + fos.flush(); + + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + if (fos != null) { + try { + fos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(dcimFile))); + return dcimFile.getAbsolutePath(); + } + + + /** + * 将视频文件保存到相册 + * + * @param videoFile File + * @return Uri? + */ + + public static String addVideoToAlbum(Context context, File videoFile) { + if (videoFile == null) return null; + File fileDir = new File(exportVideoDir); + File dcimFile; + if (fileDir.exists()) { + dcimFile = new File(exportVideoDir, getCurrentVideoFileName()); + } else { + dcimFile = new File(videoFilePath, getCurrentVideoFileName()); + } + if (dcimFile.exists()) { + dcimFile.delete(); + } + BufferedInputStream bis = null; + BufferedOutputStream bos = null; + try { + bis = new BufferedInputStream(new FileInputStream(videoFile)); + bos = new BufferedOutputStream(new FileOutputStream(dcimFile)); + byte[] bytes = new byte[1024 * 10]; + int length; + while ((length = bis.read(bytes)) != -1) { + bos.write(bytes, 0, length); + } + bos.flush(); + } catch (IOException e) { + e.printStackTrace(); + return null; + } finally { + if (bis != null) { + try { + bis.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + if (bos != null) { + try { + bos.close(); + } catch (IOException e) { + e.printStackTrace(); + } + } + } + context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE, Uri.fromFile(dcimFile))); + return dcimFile.getAbsolutePath(); + } + + + /** + * 将Assets文件拷贝到应用作用域存储 + * + * @param context Context + * @param assetsPath String + * @param fileName String + */ + public static String copyAssetsToExternalFilesDir(Context context, String assetsPath, String fileName) { + File fileDir = new File(getExternalFileDir(context).getPath() + File.separator + "assets"); + if (!fileDir.exists()) { + fileDir.mkdirs(); + } + File file = new File(fileDir, fileName); + if (file.exists()) { + return file.getAbsolutePath(); + } + try { + InputStream inputStream = context.getAssets().open(assetsPath); + FileOutputStream fos = new FileOutputStream(file); + BufferedInputStream bis = new BufferedInputStream(inputStream); + BufferedOutputStream bos = new BufferedOutputStream(fos); + byte[] byteArray = new byte[1024]; + int bytes = bis.read(byteArray); + while (bytes > 0) { + bos.write(byteArray, 0, bytes); + bos.flush(); + bytes = bis.read(byteArray); + } + bos.close(); + fos.close(); + return file.getAbsolutePath(); + } catch (IOException e) { + e.printStackTrace(); + } + return null; + } + + + /** + * 获取Uri文件绝对路径 + * + * @param context: Context + * @param uri Uri + * @return String + */ + public static String getFilePathByUri(Context context, Uri uri) { + if (uri == null) return null; + return Uri2PathUtil.getRealPathFromUri(context, uri); + } + + private static String getDataColumn(Context context, Uri uri, String selection, String[] selectionArgs) { + Cursor cursor = null; + String[] projection = new String[]{MediaStore.Images.Media.DATA}; + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null); + if (cursor != null && cursor.moveToFirst()) { + int index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA); + return cursor.getString(index); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + return null; + } + + + /** + * load本地图片 + * + * @param path + * @param screenWidth + * @return + */ + public static Bitmap loadBitmapFromExternal(String path, int screenWidth) { + BitmapFactory.Options opt = new BitmapFactory.Options(); + opt.inJustDecodeBounds = true; + BitmapFactory.decodeFile(path, opt); + int picWidth = opt.outWidth; + int picHeight = opt.outHeight; + opt.inSampleSize = 1; + // 根据屏的大小和图片大小计算出缩放比例 + if (picWidth > picHeight) { + if (picHeight > screenWidth) { + opt.inSampleSize = picHeight / screenWidth; + } + } else { + if (picWidth > screenWidth) { + opt.inSampleSize = picWidth / screenWidth; + } + } + opt.inJustDecodeBounds = false; + Bitmap bitmap = BitmapFactory.decodeFile(path, opt); + int orientation = getPhotoOrientation(path); + bitmap = rotateBitmap(bitmap, orientation); + return bitmap; + } + + /** + * load本地图片 + * + * @param path String + * @param screenWidth Int + * @param screenHeight Int + * @return Bitmap + */ + public static Bitmap loadBitmapFromExternal(String path, int screenWidth, int screenHeight) { + BitmapFactory.Options opt = new BitmapFactory.Options(); + opt.inJustDecodeBounds = true; + BitmapFactory.decodeFile(path, opt); + int picWidth = opt.outWidth; + int picHeight = opt.outHeight; + int inSampleSize = 1; + // 根据屏的大小和图片大小计算出缩放比例 + if (picHeight > screenHeight || picWidth > screenWidth) { + int halfHeight = picHeight / 2; + int halfWidth = picWidth / 2; + while (halfHeight / inSampleSize >= screenHeight && halfWidth / inSampleSize >= screenWidth) { + inSampleSize *= 2; + } + } + opt.inSampleSize = inSampleSize; + opt.inJustDecodeBounds = false; + Bitmap bitmap = BitmapFactory.decodeFile(path, opt); + int orientation = getPhotoOrientation(path); + bitmap = rotateBitmap(bitmap, orientation); + return bitmap; + } + + + /** + * 旋转 Bitmap + * + * @param bitmap + * @param orientation + * @return + */ + private static Bitmap rotateBitmap(Bitmap bitmap, int orientation) { + if (orientation == 90 || orientation == 180 || orientation == 270) { + Matrix matrix = new Matrix(); + matrix.postRotate((float) orientation); + bitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true); + } + return bitmap; + } + + + /** + * 获取图片的方向 + * + * @param path + * @return + */ + public static int getPhotoOrientation(String path) { + int orientation = 0; + int tagOrientation = 0; + try { + tagOrientation = new ExifInterface(path).getAttributeInt(ExifInterface.TAG_ORIENTATION, -1); + } catch (IOException e) { + e.printStackTrace(); + } + switch (tagOrientation) { + case ExifInterface.ORIENTATION_ROTATE_90: + orientation = 90; + break; + + case ExifInterface.ORIENTATION_ROTATE_180: + orientation = 180; + break; + + case ExifInterface.ORIENTATION_ROTATE_270: + orientation = 270; + break; + } + return orientation; + } + + + /** + * 选中图片 + * + * @param activity Activity + */ + public static void pickImageFile(Activity activity, int requestCode) { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("image/*"); + activity.startActivityForResult(intent, requestCode); + } + + /** + * 选中视频 + * + * @param activity Activity + * 回调可参考下方 + */ + public static void pickVideoFile(Activity activity, int requestCode) { + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("video/*"); + activity.startActivityForResult(intent, requestCode); + } + + /** + * 根据路径获取InputStream + * + * @param context Context + * @param path String + * @return InputStream? + */ + public static InputStream readInputStreamByPath(Context context, String path) { + if (path == null || path.trim().length() == 0) + return null; + InputStream inputStream = null; + try { + inputStream = context.getAssets().open(path); + } catch (IOException e1) { + try { + inputStream = new FileInputStream(path); + } catch (IOException e2) { + e2.printStackTrace(); + } + } + return inputStream; + } + + /** + * 相机byte转bitmap + * + * @param buffer + * @param width + * @param height + * @return + */ + public static Bitmap bytes2Bitmap(byte[] buffer, int width, int height) { + YuvImage yuvimage = new YuvImage(buffer, ImageFormat.NV21, width, height, null);//20、20分别是图的宽度与高度 + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + yuvimage.compressToJpeg(new Rect(0, 0, width, height), 80, baos);//80--JPG图片的质量[0-100],100最高 + byte[] jdata = baos.toByteArray(); + return BitmapFactory.decodeByteArray(baos.toByteArray(), 0, jdata.length); + } + + /** + * 遍历一个文件夹获取改文件夹下所有文件名 + * @param path + * @return + */ + public static ArrayList getFileList(String path) { + ArrayList fileList = new ArrayList<>(); + File dir = new File(path); + // 该文件目录下文件全部放入数组 + File[] files = dir.listFiles(); + if (files != null) { + for (int i = 0; i < files.length; i++) { + // 判断是文件还是文件夹 + if (files[i].isDirectory()) { + // 获取文件绝对路径 + getFileList(files[i].getAbsolutePath()); + // 判断文件名是否以.jpg结尾 + } else { + fileList.add(files[i].getName()); + } + } + } + return fileList; + } + + /** + * 校验文件是否是图片 + * + * @param path String + * @return Boolean + */ + public static Boolean checkIsImage(String path) { + String name = new File(path).getName().toLowerCase(); + return (name.endsWith(IMAGE_FORMAT_PNG) || name.endsWith(IMAGE_FORMAT_JPG) + || name.endsWith(IMAGE_FORMAT_JPEG)); + } + + /** + * 校验文件是否是视频 + * + * @param path String + * @return Boolean + */ + public static Boolean checkIsVideo(Context context,String path) { + MediaMetadataRetriever retriever = new MediaMetadataRetriever(); + try { + retriever.setDataSource(context, Uri.fromFile(new File(path))); + String hasVideo = retriever.extractMetadata(MediaMetadataRetriever.METADATA_KEY_HAS_VIDEO); + return "yes".equals(hasVideo); + } catch (Exception e) { + e.printStackTrace(); + } + return false; + } +} diff --git a/FaceUnity/src/main/java/com/yunbao/faceunity/utils/Uri2PathUtil.java b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/Uri2PathUtil.java new file mode 100644 index 000000000..01af25574 --- /dev/null +++ b/FaceUnity/src/main/java/com/yunbao/faceunity/utils/Uri2PathUtil.java @@ -0,0 +1,161 @@ +package com.yunbao.faceunity.utils; + +import android.annotation.TargetApi; +import android.content.ContentUris; +import android.content.Context; +import android.database.Cursor; +import android.net.Uri; +import android.os.Build; +import android.os.Environment; +import android.provider.DocumentsContract; +import android.provider.MediaStore; + +import androidx.loader.content.CursorLoader; + +public class Uri2PathUtil { + + //复杂版处理 (适配多种API) + public static String getRealPathFromUri(Context context, Uri uri) { + int sdkVersion = Build.VERSION.SDK_INT; + if (sdkVersion < 11) return getRealPathFromUri_BelowApi11(context, uri); + if (sdkVersion < 19) return getRealPathFromUri_Api11To18(context, uri); + else return getRealPathFromUri_AboveApi19(context, uri); + } + + /** + * 适配api19以上,根据uri获取图片的绝对路径 + */ + @TargetApi(Build.VERSION_CODES.KITKAT) + private static String getRealPathFromUri_AboveApi19(Context context, Uri uri) { + if (DocumentsContract.isDocumentUri(context, uri)) { + if (isExternalStorageDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + if ("primary".equalsIgnoreCase(type)) { + return Environment.getExternalStorageDirectory() + "/" + split[1]; + } + } else if (isDownloadsDocument(uri)) { + final String id = DocumentsContract.getDocumentId(uri); + final Uri contentUri = ContentUris.withAppendedId( + Uri.parse("content://downloads/public_downloads"), Long.valueOf(id)); + + return getDataColumn(context, contentUri, null, null); + } else if (isMediaDocument(uri)) { + final String docId = DocumentsContract.getDocumentId(uri); + final String[] split = docId.split(":"); + final String type = split[0]; + + Uri contentUri; + if ("image".equals(type)) { + contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI; + } else if ("video".equals(type)) { + contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI; + } else if ("audio".equals(type)) { + contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI; + } else { + contentUri = MediaStore.Files.getContentUri("external"); + } + + final String selection = "_id=?"; + final String[] selectionArgs = new String[]{split[1]}; + return getDataColumn(context, contentUri, selection, selectionArgs); + } + + + } else if ("content".equalsIgnoreCase(uri.getScheme())) { + return getDataColumn(context, uri, null, null); + } else if ("file".equalsIgnoreCase(uri.getScheme())) { + return uri.getPath(); + } + + return null; + } + + /** + * 适配api11-api18,根据uri获取图片的绝对路径 + */ + private static String getRealPathFromUri_Api11To18(Context context, Uri uri) { + String filePath = null; + String[] projection = {MediaStore.Images.Media.DATA}; + //这个有两个包不知道是哪个。。。。不过这个复杂版一般用不到 + CursorLoader loader = new CursorLoader(context, uri, projection, null, null, null); + Cursor cursor = loader.loadInBackground(); + + if (cursor != null) { + cursor.moveToFirst(); + filePath = cursor.getString(cursor.getColumnIndex(projection[0])); + cursor.close(); + } + return filePath; + } + + /** + * 适配api11以下(不包括api11),根据uri获取图片的绝对路径 + */ + private static String getRealPathFromUri_BelowApi11(Context context, Uri uri) { + String filePath = null; + String[] projection = {MediaStore.Images.Media.DATA}; + Cursor cursor = context.getContentResolver().query(uri, projection, null, null, null); + if (cursor != null && cursor.moveToFirst()) { + filePath = cursor.getString(cursor.getColumnIndex(projection[0])); + cursor.close(); + } + return filePath; + } + + /** + * Get the value of the data column for this Uri. This is useful for + * MediaStore Uris, and other file-based ContentProviders. + * + * @param context The context. + * @param uri The Uri to query. + * @param selection (Optional) Filter used in the query. + * @param selectionArgs (Optional) Selection arguments used in the query. + * @return The value of the _data column, which is typically a file path. + */ + public static String getDataColumn(Context context, Uri uri, String selection, + String[] selectionArgs) { + Cursor cursor = null; + String column = MediaStore.MediaColumns.DATA; + String[] projection = {column}; + try { + cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, + null); + if (cursor != null && cursor.moveToFirst()) { + int column_index = cursor.getColumnIndexOrThrow(column); + return cursor.getString(column_index); + } + } catch (Exception e) { + e.printStackTrace(); + } finally { + if (cursor != null) + cursor.close(); + } + return null; + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is ExternalStorageProvider. + */ + public static boolean isExternalStorageDocument(Uri uri) { + return "com.android.externalstorage.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is DownloadsProvider. + */ + public static boolean isDownloadsDocument(Uri uri) { + return "com.android.providers.downloads.documents".equals(uri.getAuthority()); + } + + /** + * @param uri The Uri to check. + * @return Whether the Uri authority is MediaProvider. + */ + public static boolean isMediaDocument(Uri uri) { + return "com.android.providers.media.documents".equals(uri.getAuthority()); + } +} \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_1_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_1_selector.xml new file mode 100644 index 000000000..6e6c49955 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_1_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_2_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_2_selector.xml new file mode 100644 index 000000000..948076d08 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_2_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_3_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_3_selector.xml new file mode 100644 index 000000000..059f1038e --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_3_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_4_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_4_selector.xml new file mode 100644 index 000000000..dc26d6db9 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_4_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_5_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_5_selector.xml new file mode 100644 index 000000000..4a80098ed --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_5_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_6_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_6_selector.xml new file mode 100644 index 000000000..977e13236 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_6_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_7_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_7_selector.xml new file mode 100644 index 000000000..4f19a5bac --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_7_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_beauty_style_none_selector.xml b/FaceUnity/src/main/res/drawable/icon_beauty_style_none_selector.xml new file mode 100644 index 000000000..04cd43a81 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_beauty_style_none_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_color_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_color_selector.xml new file mode 100644 index 000000000..72739e218 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_color_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_safe_area_close_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_safe_area_close_selector.xml new file mode 100644 index 000000000..ba35bae71 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_safe_area_close_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_safe_area_open_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_safe_area_open_selector.xml new file mode 100644 index 000000000..984f952a9 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_safe_area_open_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_similarityr_close_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_similarityr_close_selector.xml new file mode 100644 index 000000000..87c9aee8b --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_similarityr_close_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_similarityr_open_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_similarityr_open_selector.xml new file mode 100644 index 000000000..52e0f381b --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_similarityr_open_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_smooth_close_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_smooth_close_selector.xml new file mode 100644 index 000000000..30bdffb22 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_smooth_close_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_smooth_open_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_smooth_open_selector.xml new file mode 100644 index 000000000..e604dacaa --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_smooth_open_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_transparency_close_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_transparency_close_selector.xml new file mode 100644 index 000000000..20c757d1c --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_transparency_close_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/drawable/icon_green_transparency_open_selector.xml b/FaceUnity/src/main/res/drawable/icon_green_transparency_open_selector.xml new file mode 100644 index 000000000..3ee451af8 --- /dev/null +++ b/FaceUnity/src/main/res/drawable/icon_green_transparency_open_selector.xml @@ -0,0 +1,5 @@ + + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/layout/layout_animo_control.xml b/FaceUnity/src/main/res/layout/layout_animo_control.xml new file mode 100644 index 000000000..7edcd738b --- /dev/null +++ b/FaceUnity/src/main/res/layout/layout_animo_control.xml @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + diff --git a/FaceUnity/src/main/res/layout/layout_body_beauty_control.xml b/FaceUnity/src/main/res/layout/layout_body_beauty_control.xml index 4e0a6779d..456a31925 100644 --- a/FaceUnity/src/main/res/layout/layout_body_beauty_control.xml +++ b/FaceUnity/src/main/res/layout/layout_body_beauty_control.xml @@ -3,96 +3,79 @@ xmlns:app="http://schemas.android.com/apk/res-auto" android:id="@+id/cyt_main" android:layout_width="match_parent" - android:layout_height="wrap_content" + android:layout_height="@dimen/x268" + android:background="#BD050F14" + android:gravity="center_horizontal" android:orientation="vertical"> - + + - - + android:layout_height="@dimen/x180" + android:layout_gravity="bottom" + android:orientation="horizontal"> + android:gravity="center_horizontal" + android:orientation="vertical"> - - - + - - - - - - - + + + + \ No newline at end of file diff --git a/FaceUnity/src/main/res/layout/layout_face_beauty_control.xml b/FaceUnity/src/main/res/layout/layout_face_beauty_control.xml index d6c7f488a..07307f4f5 100644 --- a/FaceUnity/src/main/res/layout/layout_face_beauty_control.xml +++ b/FaceUnity/src/main/res/layout/layout_face_beauty_control.xml @@ -2,20 +2,33 @@ - - + android:layout_height="wrap_content"> + + + +