Author SHA1 Message Date
xsl c6db16a52b 交换链同步改写,加入日志 2025-11-06 17:51:10 +08:00
1152 changed files with 426 additions and 188993 deletions
+10 -50
View File
@@ -1,40 +1,25 @@
cmake_minimum_required(VERSION 3.22.1) cmake_minimum_required(VERSION 3.22.1)
project("face_sdk") project("sample")
set(CMAKE_CXX_STANDARD 20) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON) set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF) set(CMAKE_CXX_EXTENSIONS OFF)
if(MSVC)
add_compile_options(/Zc:__cplusplus)
endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Android") if(CMAKE_SYSTEM_NAME STREQUAL "Android")
message(STATUS "Building for Android") message(STATUS "Building for Android")
include_directories( include_directories(
vulkan vulkan
third_party/glm
third_party/vma
third_party/vma/include
) )
add_library(face_sdk SHARED add_library(sample SHARED
app/src/main/cpp/main.cpp app/src/main/cpp/main.cpp
app/src/main/cpp/AndroidOut.cpp app/src/main/cpp/AndroidOut.cpp
vulkan/AppBase.h vulkan/AppBase.h
vulkan/AppBase.cpp vulkan/AppBase.cpp
vulkan/Application.h vulkan/Application.h
vulkan/Application.cpp vulkan/Application.cpp
vulkan/FaceApp.h
vulkan/FaceApp.cpp
vulkan/lodepng.cpp
third_party/vma/src/VmaUsage.h
third_party/vma/src/VmaUsage.cpp
) )
find_package(game-activity REQUIRED CONFIG) find_package(game-activity REQUIRED CONFIG)
@@ -45,36 +30,22 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Android")
find_package(Vulkan REQUIRED) find_package(Vulkan REQUIRED)
target_link_libraries(face_sdk target_link_libraries(sample
game-activity::game-activity_static game-activity::game-activity_static
Vulkan::Vulkan Vulkan::Vulkan
android android
log) log)
target_compile_definitions(face_sdk PRIVATE
VMA_STATIC_VULKAN_FUNCTIONS=0
VMA_DYNAMIC_VULKAN_FUNCTIONS=1
)
endif() endif()
if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR WIN32) if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR WIN32)
message(STATUS "Building for Windows") message(STATUS "Building for Windows")
add_compile_options(/utf-8)
add_compile_definitions(_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING)
include_directories( include_directories(
${CMAKE_CURRENT_LIST_DIR}/vulkan
${CMAKE_CURRENT_LIST_DIR}/third_party
${CMAKE_CURRENT_LIST_DIR}/third_party/glm
${CMAKE_CURRENT_LIST_DIR}/third_party/vma
${CMAKE_CURRENT_LIST_DIR}/third_party/vma/include
"third_party/glfw-3.4/output/include" "third_party/glfw-3.4/output/include"
"C:/VulkanSDK/1.4.321.1/Include" "C:/VulkanSDK/1.4.321.1/Include"
) )
link_libraries( link_libraries(
# "${CMAKE_CURRENT_LIST_DIR}/third_party/glfw-3.4/output/lib/glfw3.lib" # "${CMAKE_CURRENT_LIST_DIR}/third_party/glfw-3.4/output/lib/glfw3.lib"
"${CMAKE_CURRENT_LIST_DIR}/third_party/glfw-3.4/output/glfw3.lib" "${CMAKE_CURRENT_LIST_DIR}/third_party/glfw-3.4/output/glfw3.lib"
@@ -82,22 +53,11 @@ if(CMAKE_SYSTEM_NAME STREQUAL "Windows" OR WIN32)
) )
# 将源代码添加到此项目的可执行文件。 # 将源代码添加到此项目的可执行文件。
add_executable (face_sdk add_executable (sample
vulkan/AppBase.h "vulkan/main.cpp"
vulkan/AppBase.cpp "vulkan/AppBase.h"
vulkan/Application.h "vulkan/AppBase.cpp"
vulkan/Application.cpp "vulkan/Application.h"
vulkan/FaceApp.h "vulkan/Application.cpp"
vulkan/FaceApp.cpp
vulkan/main.cpp
vulkan/lodepng.cpp
third_party/vma/src/VmaUsage.h
third_party/vma/src/VmaUsage.cpp
) )
endif() endif()
# target_compile_definitions(face_sdk PRIVATE VK_NO_PROTOTYPES) 使用volk 动态加载的时候需要定义,不自动生成vulkan接口
target_compile_definitions(face_sdk PRIVATE GLM_ENABLE_EXPERIMENTAL)
# target_compile_definitions(face_sdk PRIVATE VULKAN_HPP_NO_STRUCT_CONSTRUCTORS) 解决vs 编译c++ 20 不支持新构造函数的特性
+8 -75
View File
@@ -1,20 +1,18 @@
plugins { plugins {
//alias(libs.plugins.android.application) alias(libs.plugins.android.application)
alias(libs.plugins.android.library)
alias(libs.plugins.kotlin.android)
//id 'org.jetbrains.kotlin.android'
} }
ext.vvl_version='1.4.321.0' ext.vvl_version='1.4.321.0'
apply from: "./download_vvl.gradle" apply from: "./download_vvl.gradle"
android { android {
namespace 'com.hmwl.face_sdk' namespace 'com.hmwl.sample'
compileSdk 36 compileSdk 35
defaultConfig { defaultConfig {
//applicationId "com.hmwl.face_sdk" applicationId "com.hmwl.sample"
minSdk 30 minSdk 30
targetSdk 36 targetSdk 35
versionCode 1 versionCode 1
versionName "1.0" versionName "1.0"
@@ -23,25 +21,12 @@ android {
} }
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner" testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
consumerProguardFiles "consumer-rules.pro"
} }
buildTypes { buildTypes {
debug { debug {
debuggable true debuggable true
jniDebuggable true jniDebuggable true
externalNativeBuild {
cmake {
arguments "-DCMAKE_BUILD_TYPE=Debug"
cppFlags "-DDEBUG -O0 -g"
}
}
ndk {
debugSymbolLevel 'FULL' // Debug 版本包含完整符号
}
} }
release { release {
@@ -50,54 +35,18 @@ android {
} }
} }
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_17 sourceCompatibility JavaVersion.VERSION_21
targetCompatibility JavaVersion.VERSION_17 targetCompatibility JavaVersion.VERSION_21
} }
// 添加 Kotlin 编译选项
// kotlinOptions {
// jvmTarget = '17' // 与 Java 版本保持一致
// }
// kotlin {
// jvmToolchain(17)
// }
buildFeatures { buildFeatures {
prefab true prefab true
} }
sourceSets {
main {
jniLibs.srcDirs += [
'libs/tasks-vision/jni',
'libs/tasks-core/jni'
]
//java.srcDirs += [
// 'libs/tasks-vision/vision_classes',
// 'libs/tasks-core/core_classes'
//]
res.srcDirs += [
'libs/tasks-vision/res',
'libs/tasks-core/res'
]
}
}
externalNativeBuild { externalNativeBuild {
cmake { cmake {
path file('../CMakeLists.txt') path file('../CMakeLists.txt')
version '3.22.1' version '3.22.1'
} }
} }
packagingOptions {
pickFirst '**/*.jar'
}
kotlinOptions {
jvmTarget = '17'
}
} }
dependencies { dependencies {
@@ -105,23 +54,7 @@ dependencies {
implementation libs.appcompat implementation libs.appcompat
implementation libs.material implementation libs.material
implementation libs.games.activity implementation libs.games.activity
implementation libs.androidx.core.core.ktx
testImplementation libs.junit testImplementation libs.junit
androidTestImplementation libs.ext.junit androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core androidTestImplementation libs.espresso.core
implementation 'com.google.protobuf:protobuf-javalite:3.21.12'
implementation files('libs/tasks-vision.jar', 'libs/tasks-core.jar')
//implementation fileTree(dir: 'libs/tasks-vision', include: ['*.jar'])
//implementation fileTree(dir: 'libs/tasks-core', include: ['*.jar'])
def camerax_version = '1.4.2'
implementation "androidx.camera:camera-core:$camerax_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:$camerax_version"
} }
+1 -2
View File
@@ -1,5 +1,4 @@
//apply plugin: 'com.android.application' apply plugin: 'com.android.application'
apply plugin: 'com.android.library'
/* /*
* Copyright (c) 2022-2024, The Android Open Source Project. * Copyright (c) 2022-2024, The Android Open Source Project.
Binary file not shown.
Binary file not shown.
-9
View File
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.mediapipe.tasks.core" >
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="34" />
</manifest>
-255
View File
@@ -1,255 +0,0 @@
int anim fragment_fast_out_extra_slow_in 0x00000000
int animator fragment_close_enter 0x00000000
int animator fragment_close_exit 0x00000000
int animator fragment_fade_enter 0x00000000
int animator fragment_fade_exit 0x00000000
int animator fragment_open_enter 0x00000000
int animator fragment_open_exit 0x00000000
int attr alpha 0x00000000
int attr coordinatorLayoutStyle 0x00000000
int attr font 0x00000000
int attr fontProviderAuthority 0x00000000
int attr fontProviderCerts 0x00000000
int attr fontProviderFetchStrategy 0x00000000
int attr fontProviderFetchTimeout 0x00000000
int attr fontProviderPackage 0x00000000
int attr fontProviderQuery 0x00000000
int attr fontStyle 0x00000000
int attr fontVariationSettings 0x00000000
int attr fontWeight 0x00000000
int attr keylines 0x00000000
int attr layout_anchor 0x00000000
int attr layout_anchorGravity 0x00000000
int attr layout_behavior 0x00000000
int attr layout_dodgeInsetEdges 0x00000000
int attr layout_insetEdge 0x00000000
int attr layout_keyline 0x00000000
int attr statusBarBackground 0x00000000
int attr ttcIndex 0x00000000
int color notification_action_color_filter 0x00000000
int color notification_icon_bg_color 0x00000000
int color notification_material_background_media_default_color 0x00000000
int color primary_text_default_material_dark 0x00000000
int color ripple_material_light 0x00000000
int color secondary_text_default_material_dark 0x00000000
int color secondary_text_default_material_light 0x00000000
int dimen compat_button_inset_horizontal_material 0x00000000
int dimen compat_button_inset_vertical_material 0x00000000
int dimen compat_button_padding_horizontal_material 0x00000000
int dimen compat_button_padding_vertical_material 0x00000000
int dimen compat_control_corner_material 0x00000000
int dimen compat_notification_large_icon_max_height 0x00000000
int dimen compat_notification_large_icon_max_width 0x00000000
int dimen notification_action_icon_size 0x00000000
int dimen notification_action_text_size 0x00000000
int dimen notification_big_circle_margin 0x00000000
int dimen notification_content_margin_start 0x00000000
int dimen notification_large_icon_height 0x00000000
int dimen notification_large_icon_width 0x00000000
int dimen notification_main_column_padding_top 0x00000000
int dimen notification_media_narrow_margin 0x00000000
int dimen notification_right_icon_size 0x00000000
int dimen notification_right_side_padding_top 0x00000000
int dimen notification_small_icon_background_padding 0x00000000
int dimen notification_small_icon_size_as_large 0x00000000
int dimen notification_subtext_size 0x00000000
int dimen notification_top_pad 0x00000000
int dimen notification_top_pad_large_text 0x00000000
int dimen subtitle_corner_radius 0x00000000
int dimen subtitle_outline_width 0x00000000
int dimen subtitle_shadow_offset 0x00000000
int dimen subtitle_shadow_radius 0x00000000
int drawable notification_action_background 0x00000000
int drawable notification_bg 0x00000000
int drawable notification_bg_low 0x00000000
int drawable notification_bg_low_normal 0x00000000
int drawable notification_bg_low_pressed 0x00000000
int drawable notification_bg_normal 0x00000000
int drawable notification_bg_normal_pressed 0x00000000
int drawable notification_icon_background 0x00000000
int drawable notification_template_icon_bg 0x00000000
int drawable notification_template_icon_low_bg 0x00000000
int drawable notification_tile_bg 0x00000000
int drawable notify_panel_notification_icon_bg 0x00000000
int id accessibility_action_clickable_span 0x00000000
int id accessibility_custom_action_0 0x00000000
int id accessibility_custom_action_1 0x00000000
int id accessibility_custom_action_10 0x00000000
int id accessibility_custom_action_11 0x00000000
int id accessibility_custom_action_12 0x00000000
int id accessibility_custom_action_13 0x00000000
int id accessibility_custom_action_14 0x00000000
int id accessibility_custom_action_15 0x00000000
int id accessibility_custom_action_16 0x00000000
int id accessibility_custom_action_17 0x00000000
int id accessibility_custom_action_18 0x00000000
int id accessibility_custom_action_19 0x00000000
int id accessibility_custom_action_2 0x00000000
int id accessibility_custom_action_20 0x00000000
int id accessibility_custom_action_21 0x00000000
int id accessibility_custom_action_22 0x00000000
int id accessibility_custom_action_23 0x00000000
int id accessibility_custom_action_24 0x00000000
int id accessibility_custom_action_25 0x00000000
int id accessibility_custom_action_26 0x00000000
int id accessibility_custom_action_27 0x00000000
int id accessibility_custom_action_28 0x00000000
int id accessibility_custom_action_29 0x00000000
int id accessibility_custom_action_3 0x00000000
int id accessibility_custom_action_30 0x00000000
int id accessibility_custom_action_31 0x00000000
int id accessibility_custom_action_4 0x00000000
int id accessibility_custom_action_5 0x00000000
int id accessibility_custom_action_6 0x00000000
int id accessibility_custom_action_7 0x00000000
int id accessibility_custom_action_8 0x00000000
int id accessibility_custom_action_9 0x00000000
int id action0 0x00000000
int id action_container 0x00000000
int id action_divider 0x00000000
int id action_image 0x00000000
int id action_text 0x00000000
int id actions 0x00000000
int id all 0x00000000
int id async 0x00000000
int id blocking 0x00000000
int id bottom 0x00000000
int id cancel_action 0x00000000
int id center 0x00000000
int id center_horizontal 0x00000000
int id center_vertical 0x00000000
int id chronometer 0x00000000
int id clip_horizontal 0x00000000
int id clip_vertical 0x00000000
int id dialog_button 0x00000000
int id end 0x00000000
int id end_padder 0x00000000
int id fill 0x00000000
int id fill_horizontal 0x00000000
int id fill_vertical 0x00000000
int id forever 0x00000000
int id fragment_container_view_tag 0x00000000
int id icon 0x00000000
int id icon_group 0x00000000
int id info 0x00000000
int id italic 0x00000000
int id left 0x00000000
int id line1 0x00000000
int id line3 0x00000000
int id media_actions 0x00000000
int id none 0x00000000
int id normal 0x00000000
int id notification_background 0x00000000
int id notification_main_column 0x00000000
int id notification_main_column_container 0x00000000
int id right 0x00000000
int id right_icon 0x00000000
int id right_side 0x00000000
int id special_effects_controller_view_tag 0x00000000
int id start 0x00000000
int id status_bar_latest_event_content 0x00000000
int id tag_accessibility_actions 0x00000000
int id tag_accessibility_clickable_spans 0x00000000
int id tag_accessibility_heading 0x00000000
int id tag_accessibility_pane_title 0x00000000
int id tag_screen_reader_focusable 0x00000000
int id tag_transition_group 0x00000000
int id tag_unhandled_key_event_manager 0x00000000
int id tag_unhandled_key_listeners 0x00000000
int id text 0x00000000
int id text2 0x00000000
int id time 0x00000000
int id title 0x00000000
int id top 0x00000000
int id view_tree_lifecycle_owner 0x00000000
int id view_tree_saved_state_registry_owner 0x00000000
int id view_tree_view_model_store_owner 0x00000000
int id visible_removing_fragment_view_tag 0x00000000
int integer cancel_button_image_alpha 0x00000000
int integer status_bar_notification_info_maxnum 0x00000000
int layout custom_dialog 0x00000000
int layout notification_action 0x00000000
int layout notification_action_tombstone 0x00000000
int layout notification_media_action 0x00000000
int layout notification_media_cancel_action 0x00000000
int layout notification_template_big_media 0x00000000
int layout notification_template_big_media_custom 0x00000000
int layout notification_template_big_media_narrow 0x00000000
int layout notification_template_big_media_narrow_custom 0x00000000
int layout notification_template_custom_big 0x00000000
int layout notification_template_icon_group 0x00000000
int layout notification_template_lines_media 0x00000000
int layout notification_template_media 0x00000000
int layout notification_template_media_custom 0x00000000
int layout notification_template_part_chronometer 0x00000000
int layout notification_template_part_time 0x00000000
int string status_bar_notification_info_overflow 0x00000000
int style TextAppearance_Compat_Notification 0x00000000
int style TextAppearance_Compat_Notification_Info 0x00000000
int style TextAppearance_Compat_Notification_Info_Media 0x00000000
int style TextAppearance_Compat_Notification_Line2 0x00000000
int style TextAppearance_Compat_Notification_Line2_Media 0x00000000
int style TextAppearance_Compat_Notification_Media 0x00000000
int style TextAppearance_Compat_Notification_Time 0x00000000
int style TextAppearance_Compat_Notification_Time_Media 0x00000000
int style TextAppearance_Compat_Notification_Title 0x00000000
int style TextAppearance_Compat_Notification_Title_Media 0x00000000
int style Widget_Compat_NotificationActionContainer 0x00000000
int style Widget_Compat_NotificationActionText 0x00000000
int style Widget_Support_CoordinatorLayout 0x00000000
int[] styleable ColorStateListItem { 0x010101a5, 0x0101031f, 0x00000000 }
int styleable ColorStateListItem_android_color 0
int styleable ColorStateListItem_android_alpha 1
int styleable ColorStateListItem_alpha 2
int[] styleable CoordinatorLayout { 0x00000000, 0x00000000 }
int styleable CoordinatorLayout_keylines 0
int styleable CoordinatorLayout_statusBarBackground 1
int[] styleable CoordinatorLayout_Layout { 0x010100b3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
int styleable CoordinatorLayout_Layout_android_layout_gravity 0
int styleable CoordinatorLayout_Layout_layout_anchor 1
int styleable CoordinatorLayout_Layout_layout_anchorGravity 2
int styleable CoordinatorLayout_Layout_layout_behavior 3
int styleable CoordinatorLayout_Layout_layout_dodgeInsetEdges 4
int styleable CoordinatorLayout_Layout_layout_insetEdge 5
int styleable CoordinatorLayout_Layout_layout_keyline 6
int[] styleable FontFamily { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
int styleable FontFamily_fontProviderAuthority 0
int styleable FontFamily_fontProviderCerts 1
int styleable FontFamily_fontProviderFetchStrategy 2
int styleable FontFamily_fontProviderFetchTimeout 3
int styleable FontFamily_fontProviderPackage 4
int styleable FontFamily_fontProviderQuery 5
int[] styleable FontFamilyFont { 0x01010532, 0x01010533, 0x0101053f, 0x0101056f, 0x01010570, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
int styleable FontFamilyFont_android_font 0
int styleable FontFamilyFont_android_fontWeight 1
int styleable FontFamilyFont_android_fontStyle 2
int styleable FontFamilyFont_android_ttcIndex 3
int styleable FontFamilyFont_android_fontVariationSettings 4
int styleable FontFamilyFont_font 5
int styleable FontFamilyFont_fontStyle 6
int styleable FontFamilyFont_fontVariationSettings 7
int styleable FontFamilyFont_fontWeight 8
int styleable FontFamilyFont_ttcIndex 9
int[] styleable Fragment { 0x01010003, 0x010100d0, 0x010100d1 }
int styleable Fragment_android_name 0
int styleable Fragment_android_id 1
int styleable Fragment_android_tag 2
int[] styleable FragmentContainerView { 0x01010003, 0x010100d1 }
int styleable FragmentContainerView_android_name 0
int styleable FragmentContainerView_android_tag 1
int[] styleable GradientColor { 0x0101019d, 0x0101019e, 0x010101a1, 0x010101a2, 0x010101a3, 0x010101a4, 0x01010201, 0x0101020b, 0x01010510, 0x01010511, 0x01010512, 0x01010513 }
int styleable GradientColor_android_startColor 0
int styleable GradientColor_android_endColor 1
int styleable GradientColor_android_type 2
int styleable GradientColor_android_centerX 3
int styleable GradientColor_android_centerY 4
int styleable GradientColor_android_gradientRadius 5
int styleable GradientColor_android_tileMode 6
int styleable GradientColor_android_centerColor 7
int styleable GradientColor_android_startX 8
int styleable GradientColor_android_startY 9
int styleable GradientColor_android_endX 10
int styleable GradientColor_android_endY 11
int[] styleable GradientColorItem { 0x010101a5, 0x01010514 }
int styleable GradientColorItem_android_color 0
int styleable GradientColorItem_android_offset 1
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,9 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.google.mediapipe.tasks.vision" >
<uses-sdk
android:minSdkVersion="24"
android:targetSdkVersion="34" />
</manifest>
-255
View File
@@ -1,255 +0,0 @@
int anim fragment_fast_out_extra_slow_in 0x00000000
int animator fragment_close_enter 0x00000000
int animator fragment_close_exit 0x00000000
int animator fragment_fade_enter 0x00000000
int animator fragment_fade_exit 0x00000000
int animator fragment_open_enter 0x00000000
int animator fragment_open_exit 0x00000000
int attr alpha 0x00000000
int attr coordinatorLayoutStyle 0x00000000
int attr font 0x00000000
int attr fontProviderAuthority 0x00000000
int attr fontProviderCerts 0x00000000
int attr fontProviderFetchStrategy 0x00000000
int attr fontProviderFetchTimeout 0x00000000
int attr fontProviderPackage 0x00000000
int attr fontProviderQuery 0x00000000
int attr fontStyle 0x00000000
int attr fontVariationSettings 0x00000000
int attr fontWeight 0x00000000
int attr keylines 0x00000000
int attr layout_anchor 0x00000000
int attr layout_anchorGravity 0x00000000
int attr layout_behavior 0x00000000
int attr layout_dodgeInsetEdges 0x00000000
int attr layout_insetEdge 0x00000000
int attr layout_keyline 0x00000000
int attr statusBarBackground 0x00000000
int attr ttcIndex 0x00000000
int color notification_action_color_filter 0x00000000
int color notification_icon_bg_color 0x00000000
int color notification_material_background_media_default_color 0x00000000
int color primary_text_default_material_dark 0x00000000
int color ripple_material_light 0x00000000
int color secondary_text_default_material_dark 0x00000000
int color secondary_text_default_material_light 0x00000000
int dimen compat_button_inset_horizontal_material 0x00000000
int dimen compat_button_inset_vertical_material 0x00000000
int dimen compat_button_padding_horizontal_material 0x00000000
int dimen compat_button_padding_vertical_material 0x00000000
int dimen compat_control_corner_material 0x00000000
int dimen compat_notification_large_icon_max_height 0x00000000
int dimen compat_notification_large_icon_max_width 0x00000000
int dimen notification_action_icon_size 0x00000000
int dimen notification_action_text_size 0x00000000
int dimen notification_big_circle_margin 0x00000000
int dimen notification_content_margin_start 0x00000000
int dimen notification_large_icon_height 0x00000000
int dimen notification_large_icon_width 0x00000000
int dimen notification_main_column_padding_top 0x00000000
int dimen notification_media_narrow_margin 0x00000000
int dimen notification_right_icon_size 0x00000000
int dimen notification_right_side_padding_top 0x00000000
int dimen notification_small_icon_background_padding 0x00000000
int dimen notification_small_icon_size_as_large 0x00000000
int dimen notification_subtext_size 0x00000000
int dimen notification_top_pad 0x00000000
int dimen notification_top_pad_large_text 0x00000000
int dimen subtitle_corner_radius 0x00000000
int dimen subtitle_outline_width 0x00000000
int dimen subtitle_shadow_offset 0x00000000
int dimen subtitle_shadow_radius 0x00000000
int drawable notification_action_background 0x00000000
int drawable notification_bg 0x00000000
int drawable notification_bg_low 0x00000000
int drawable notification_bg_low_normal 0x00000000
int drawable notification_bg_low_pressed 0x00000000
int drawable notification_bg_normal 0x00000000
int drawable notification_bg_normal_pressed 0x00000000
int drawable notification_icon_background 0x00000000
int drawable notification_template_icon_bg 0x00000000
int drawable notification_template_icon_low_bg 0x00000000
int drawable notification_tile_bg 0x00000000
int drawable notify_panel_notification_icon_bg 0x00000000
int id accessibility_action_clickable_span 0x00000000
int id accessibility_custom_action_0 0x00000000
int id accessibility_custom_action_1 0x00000000
int id accessibility_custom_action_10 0x00000000
int id accessibility_custom_action_11 0x00000000
int id accessibility_custom_action_12 0x00000000
int id accessibility_custom_action_13 0x00000000
int id accessibility_custom_action_14 0x00000000
int id accessibility_custom_action_15 0x00000000
int id accessibility_custom_action_16 0x00000000
int id accessibility_custom_action_17 0x00000000
int id accessibility_custom_action_18 0x00000000
int id accessibility_custom_action_19 0x00000000
int id accessibility_custom_action_2 0x00000000
int id accessibility_custom_action_20 0x00000000
int id accessibility_custom_action_21 0x00000000
int id accessibility_custom_action_22 0x00000000
int id accessibility_custom_action_23 0x00000000
int id accessibility_custom_action_24 0x00000000
int id accessibility_custom_action_25 0x00000000
int id accessibility_custom_action_26 0x00000000
int id accessibility_custom_action_27 0x00000000
int id accessibility_custom_action_28 0x00000000
int id accessibility_custom_action_29 0x00000000
int id accessibility_custom_action_3 0x00000000
int id accessibility_custom_action_30 0x00000000
int id accessibility_custom_action_31 0x00000000
int id accessibility_custom_action_4 0x00000000
int id accessibility_custom_action_5 0x00000000
int id accessibility_custom_action_6 0x00000000
int id accessibility_custom_action_7 0x00000000
int id accessibility_custom_action_8 0x00000000
int id accessibility_custom_action_9 0x00000000
int id action0 0x00000000
int id action_container 0x00000000
int id action_divider 0x00000000
int id action_image 0x00000000
int id action_text 0x00000000
int id actions 0x00000000
int id all 0x00000000
int id async 0x00000000
int id blocking 0x00000000
int id bottom 0x00000000
int id cancel_action 0x00000000
int id center 0x00000000
int id center_horizontal 0x00000000
int id center_vertical 0x00000000
int id chronometer 0x00000000
int id clip_horizontal 0x00000000
int id clip_vertical 0x00000000
int id dialog_button 0x00000000
int id end 0x00000000
int id end_padder 0x00000000
int id fill 0x00000000
int id fill_horizontal 0x00000000
int id fill_vertical 0x00000000
int id forever 0x00000000
int id fragment_container_view_tag 0x00000000
int id icon 0x00000000
int id icon_group 0x00000000
int id info 0x00000000
int id italic 0x00000000
int id left 0x00000000
int id line1 0x00000000
int id line3 0x00000000
int id media_actions 0x00000000
int id none 0x00000000
int id normal 0x00000000
int id notification_background 0x00000000
int id notification_main_column 0x00000000
int id notification_main_column_container 0x00000000
int id right 0x00000000
int id right_icon 0x00000000
int id right_side 0x00000000
int id special_effects_controller_view_tag 0x00000000
int id start 0x00000000
int id status_bar_latest_event_content 0x00000000
int id tag_accessibility_actions 0x00000000
int id tag_accessibility_clickable_spans 0x00000000
int id tag_accessibility_heading 0x00000000
int id tag_accessibility_pane_title 0x00000000
int id tag_screen_reader_focusable 0x00000000
int id tag_transition_group 0x00000000
int id tag_unhandled_key_event_manager 0x00000000
int id tag_unhandled_key_listeners 0x00000000
int id text 0x00000000
int id text2 0x00000000
int id time 0x00000000
int id title 0x00000000
int id top 0x00000000
int id view_tree_lifecycle_owner 0x00000000
int id view_tree_saved_state_registry_owner 0x00000000
int id view_tree_view_model_store_owner 0x00000000
int id visible_removing_fragment_view_tag 0x00000000
int integer cancel_button_image_alpha 0x00000000
int integer status_bar_notification_info_maxnum 0x00000000
int layout custom_dialog 0x00000000
int layout notification_action 0x00000000
int layout notification_action_tombstone 0x00000000
int layout notification_media_action 0x00000000
int layout notification_media_cancel_action 0x00000000
int layout notification_template_big_media 0x00000000
int layout notification_template_big_media_custom 0x00000000
int layout notification_template_big_media_narrow 0x00000000
int layout notification_template_big_media_narrow_custom 0x00000000
int layout notification_template_custom_big 0x00000000
int layout notification_template_icon_group 0x00000000
int layout notification_template_lines_media 0x00000000
int layout notification_template_media 0x00000000
int layout notification_template_media_custom 0x00000000
int layout notification_template_part_chronometer 0x00000000
int layout notification_template_part_time 0x00000000
int string status_bar_notification_info_overflow 0x00000000
int style TextAppearance_Compat_Notification 0x00000000
int style TextAppearance_Compat_Notification_Info 0x00000000
int style TextAppearance_Compat_Notification_Info_Media 0x00000000
int style TextAppearance_Compat_Notification_Line2 0x00000000
int style TextAppearance_Compat_Notification_Line2_Media 0x00000000
int style TextAppearance_Compat_Notification_Media 0x00000000
int style TextAppearance_Compat_Notification_Time 0x00000000
int style TextAppearance_Compat_Notification_Time_Media 0x00000000
int style TextAppearance_Compat_Notification_Title 0x00000000
int style TextAppearance_Compat_Notification_Title_Media 0x00000000
int style Widget_Compat_NotificationActionContainer 0x00000000
int style Widget_Compat_NotificationActionText 0x00000000
int style Widget_Support_CoordinatorLayout 0x00000000
int[] styleable ColorStateListItem { 0x010101a5, 0x0101031f, 0x00000000 }
int styleable ColorStateListItem_android_color 0
int styleable ColorStateListItem_android_alpha 1
int styleable ColorStateListItem_alpha 2
int[] styleable CoordinatorLayout { 0x00000000, 0x00000000 }
int styleable CoordinatorLayout_keylines 0
int styleable CoordinatorLayout_statusBarBackground 1
int[] styleable CoordinatorLayout_Layout { 0x010100b3, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
int styleable CoordinatorLayout_Layout_android_layout_gravity 0
int styleable CoordinatorLayout_Layout_layout_anchor 1
int styleable CoordinatorLayout_Layout_layout_anchorGravity 2
int styleable CoordinatorLayout_Layout_layout_behavior 3
int styleable CoordinatorLayout_Layout_layout_dodgeInsetEdges 4
int styleable CoordinatorLayout_Layout_layout_insetEdge 5
int styleable CoordinatorLayout_Layout_layout_keyline 6
int[] styleable FontFamily { 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
int styleable FontFamily_fontProviderAuthority 0
int styleable FontFamily_fontProviderCerts 1
int styleable FontFamily_fontProviderFetchStrategy 2
int styleable FontFamily_fontProviderFetchTimeout 3
int styleable FontFamily_fontProviderPackage 4
int styleable FontFamily_fontProviderQuery 5
int[] styleable FontFamilyFont { 0x01010532, 0x01010533, 0x0101053f, 0x0101056f, 0x01010570, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000 }
int styleable FontFamilyFont_android_font 0
int styleable FontFamilyFont_android_fontWeight 1
int styleable FontFamilyFont_android_fontStyle 2
int styleable FontFamilyFont_android_ttcIndex 3
int styleable FontFamilyFont_android_fontVariationSettings 4
int styleable FontFamilyFont_font 5
int styleable FontFamilyFont_fontStyle 6
int styleable FontFamilyFont_fontVariationSettings 7
int styleable FontFamilyFont_fontWeight 8
int styleable FontFamilyFont_ttcIndex 9
int[] styleable Fragment { 0x01010003, 0x010100d0, 0x010100d1 }
int styleable Fragment_android_name 0
int styleable Fragment_android_id 1
int styleable Fragment_android_tag 2
int[] styleable FragmentContainerView { 0x01010003, 0x010100d1 }
int styleable FragmentContainerView_android_name 0
int styleable FragmentContainerView_android_tag 1
int[] styleable GradientColor { 0x0101019d, 0x0101019e, 0x010101a1, 0x010101a2, 0x010101a3, 0x010101a4, 0x01010201, 0x0101020b, 0x01010510, 0x01010511, 0x01010512, 0x01010513 }
int styleable GradientColor_android_startColor 0
int styleable GradientColor_android_endColor 1
int styleable GradientColor_android_type 2
int styleable GradientColor_android_centerX 3
int styleable GradientColor_android_centerY 4
int styleable GradientColor_android_gradientRadius 5
int styleable GradientColor_android_tileMode 6
int styleable GradientColor_android_centerColor 7
int styleable GradientColor_android_startX 8
int styleable GradientColor_android_startY 9
int styleable GradientColor_android_endX 10
int styleable GradientColor_android_endY 11
int[] styleable GradientColorItem { 0x010101a5, 0x01010514 }
int styleable GradientColorItem_android_color 0
int styleable GradientColorItem_android_offset 1
Binary file not shown.
@@ -0,0 +1,26 @@
package com.hmwl.sample;
import android.content.Context;
import androidx.test.platform.app.InstrumentationRegistry;
import androidx.test.ext.junit.runners.AndroidJUnit4;
import org.junit.Test;
import org.junit.runner.RunWith;
import static org.junit.Assert.*;
/**
* Instrumented test, which will execute on an Android device.
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
@RunWith(AndroidJUnit4.class)
public class ExampleInstrumentedTest {
@Test
public void useAppContext() {
// Context of the app under test.
Context appContext = InstrumentationRegistry.getInstrumentation().getTargetContext();
assertEquals("com.hmwl.sample", appContext.getPackageName());
}
}
+16 -17
View File
@@ -2,28 +2,27 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android" <manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"> xmlns:tools="http://schemas.android.com/tools">
<!-- 声明摄像头硬件特性 --> <application
<uses-feature android:allowBackup="true"
android:name="android.hardware.camera" android:dataExtractionRules="@xml/data_extraction_rules"
android:required="false" /> android:fullBackupContent="@xml/backup_rules"
android:icon="@mipmap/ic_launcher"
<!-- 声明摄像头权限 --> android:label="@string/app_name"
<uses-permission android:name="android.permission.CAMERA" /> android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
<application> android:theme="@style/Theme.Sample">
<!-- 声明 MainActivity -->
<!-- 作为库,exported 通常设为 false,除非明确需要外部应用启动 -->
<activity <activity
android:name=".FaceActivity" android:name=".MainActivity"
android:exported="true" android:exported="true">
tools:ignore="MissingClass"> <!-- 如果IDE报类找不到,可以添加这个 --> <intent-filter>
<action android:name="android.intent.action.MAIN" />
<!-- 重要:移除 MAIN/LAUNCHER intent-filter --> <category android:name="android.intent.category.LAUNCHER" />
<!-- 让使用库的应用来决定哪个是主Activity --> </intent-filter>
<meta-data <meta-data
android:name="android.app.lib_name" android:name="android.app.lib_name"
android:value="face_sdk" /> android:value="sample" />
</activity> </activity>
</application> </application>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 54 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 69 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 24 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 124 KiB

Binary file not shown.
File diff suppressed because it is too large Load Diff
Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

-15
View File
@@ -1,15 +0,0 @@
#version 450
// 输入变量(与顶点着色器输出对应)
layout(location = 0) in vec2 inTexCoord;
// 输出颜色
layout(location = 0) out vec4 outColor;
// 纹理采样器
layout(binding = 0) uniform sampler2D texSampler;
void main() {
// 采样纹理
outColor = texture(texSampler, inTexCoord);
}
Binary file not shown.
-58
View File
@@ -1,58 +0,0 @@
#version 450
// 硬编码的顶点数据 - 4个顶点组成三角形带覆盖整个屏幕
// const vec2 positions[6] = vec2[6](
// vec2( 1.0, 1.0), // 右上 - 三角形1
// vec2(-1.0, 1.0), // 左上 - 三角形1
// vec2(-1.0, -1.0), // 左下 - 三角形1
// vec2(-1.0, -1.0), // 左下 - 三角形2
// vec2( 1.0, -1.0), // 右下 - 三角形2
// vec2( 1.0, 1.0) // 右上 - 三角形2
// );
const float offset = (640-480)/(480.0);
const vec2 positions[6] = vec2[6](
vec2( 1.0, -1.0 -offset), // 右下
vec2(1.0, 1.0 + offset), // 右上 - 三角形1
vec2(-1.0, 1.0 + offset), // 左上 - 三角形1
vec2(-1.0, 1.0 + offset), // 左上 - 三角形2
vec2( -1.0, -1.0-offset), // 左下 - 三角形2
vec2( 1.0, -1.0-offset) // 右下 - 三角形2
);
const vec2 texCoords[6] = vec2[6](
vec2(1.0, 1.0), // 右上
vec2(0.0, 1.0), // 左上
vec2(0.0, 0.0), // 左下
vec2(0.0, 0.0), // 左下
vec2(1.0, 0.0), // 右下
vec2(1.0, 1.0) // 右上
);
// 定义 Push Constant,只有一个 float
layout(push_constant) uniform PushConstants {
float myValue;
} pushConstants;
// 输出变量
layout(location = 0) out vec2 outTexCoord;
void main() {
// 获取顶点位置
vec2 position = positions[gl_VertexIndex];
position = position * pushConstants.myValue;
// 设置输出位置(Vulkan使用不同的坐标系)
gl_Position = vec4(position, 0.0, 1.0);
// 输出纹理坐标
outTexCoord = texCoords[gl_VertexIndex];
}
Binary file not shown.
@@ -1,43 +0,0 @@
#version 450
layout(location = 0) in vec3 fragColor;
layout(location = 1) in vec3 fragLineStart;
layout(location = 2) in vec3 fragLineEnd;
layout(location = 0) out vec4 outColor;
layout(binding = 0) uniform UniformBufferObject {
mat4 proj;
mat4 model;
mat4 view;
} ubo;
layout(binding = 1) uniform DashParameters {
float dashSize;
float gapSize;
float dashOffset;
float uAASize;
int useWorldSpace;
} dashParams;
void main() {
vec2 fragPos = gl_FragCoord.xy;
// 网格参数
float gridSize = 14.0; // 网格大小
float dotRadius = 6.0; // 点状半径
// 计算当前片段所在的网格和网格中心坐标
vec2 gridCoord = fragPos / gridSize;
vec2 gridCenter = (floor(gridCoord) + 0.5) * gridSize;
// 计算片段到网格中心的距离
float distanceToCenter = length(fragPos - gridCenter);
// 如果距离超过点状半径,丢弃(创建点状虚线)
if (distanceToCenter > dotRadius && fragColor.y > 0.5) {
discard;
}
outColor = vec4(fragColor, 1.0);
}
Binary file not shown.
@@ -1,36 +0,0 @@
#version 450
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec3 inLineStart;
layout(location = 3) in vec3 inLineEnd;
layout(location = 0) out vec3 fragColor;
layout(location = 1) out vec3 fragLineStart;
layout(location = 2) out vec3 fragLineEnd;
layout(binding = 0) uniform UniformBufferObject {
mat4 proj;
mat4 model;
mat4 view;
} ubo;
layout(push_constant) uniform PushConstants {
float myValue;
} pushConstants;
void main() {
mat4 worldviewproj = ubo.proj * ubo.view * ubo.model;
//gl_Position = worldviewproj * vec4(inPosition, 1.0);
vec2 position = vec2(inPosition.xy*2 -1);
//gl_Position = vec4(inPosition.xy*2 -1, 0.5, 1.0);
position = position * pushConstants.myValue;
gl_Position = vec4(position, 0.5, 1.0);
fragColor = inColor;
fragLineStart = (worldviewproj * vec4(inLineStart, 1.0)).xyz;
fragLineEnd = (worldviewproj * vec4(inLineEnd, 1.0)).xyz;
}
Binary file not shown.
@@ -1,11 +0,0 @@
#version 450
layout(location = 0) in vec3 fragColor;
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(1, 0, 0, 1.0);
}
@@ -1,23 +0,0 @@
#version 450
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 2) in vec3 inLineStart;
layout(location = 3) in vec3 inLineEnd;
layout(location = 0) out vec3 fragColor;
layout(binding = 0) uniform UniformBufferObject {
mat4 proj;
mat4 model;
mat4 view;
} ubo;
void main() {
//mat4 worldviewproj = ubo.proj * ubo.view * ubo.model;
mat4 mvp = ubo.proj * ubo.view * ubo.model;
//gl_Position = worldviewproj * vec4(inPosition, 1.0);
gl_Position = mvp * vec4(inPosition, 1.0);
fragColor = inColor;
}
@@ -1,11 +0,0 @@
#version 450
// 从顶点着色器接收的颜色
layout(location = 0) in vec3 fragColor;
// 输出颜色
layout(location = 0) out vec4 outColor;
void main() {
outColor = vec4(fragColor, 1.0); // 使用传入的颜色
}
Binary file not shown.
@@ -1,31 +0,0 @@
#version 450
layout(location = 0) in vec3 inPosition;
layout(location = 1) in vec3 inColor;
layout(location = 0) out vec3 fragColor;
layout(binding = 0) uniform UniformBufferObject {
mat4 proj;
mat4 model;
mat4 view;
} ubo;
layout(push_constant) uniform PushConstants {
float myValue;
} pushConstants;
void main() {
// 预计算MVP矩阵以减少乘法次数
//mat4 mvp = ubo.proj * ubo.view * ubo.model;
//vec3 pos = vec3(2.0, inPosition.y, inPosition.z);
//gl_Position = mvp * vec4(inPosition, 1.0);
vec2 position = vec2(inPosition.xy*2 -1);
//gl_Position = vec4(inPosition.xy*2 -1, 0.5, 1.0);
position = position * pushConstants.myValue;
gl_Position = vec4(position, 0.5, 1.0);
fragColor = inColor;
gl_PointSize = 2.0;
}
Binary file not shown.
Binary file not shown.
Binary file not shown.
-17
View File
@@ -1,17 +0,0 @@
#version 450
layout (binding = 1) uniform sampler2D samplerColor;
layout (location = 0) in vec2 inUV;
layout (location = 1) in vec3 inNormal;
layout (location = 0) out vec4 outFragColor;
void main()
{
vec4 color = texture(samplerColor, inUV);
outFragColor = color;
}
Binary file not shown.
-39
View File
@@ -1,39 +0,0 @@
#version 450
layout (location = 0) in vec3 inPos;
layout (location = 1) in vec2 inUV;
layout (location = 2) in vec3 inNormal;
layout (binding = 0) uniform UBO
{
mat4 projection;
mat4 model;
vec4 viewPos;
float lodBias;
} ubo;
layout (location = 0) out vec2 outUV;
layout (location = 1) out vec3 outNormal;
layout(push_constant) uniform PushConstants {
float myValue;
} pushConstants;
out gl_PerVertex
{
vec4 gl_Position;
};
void main()
{
outUV = inUV;
vec2 position = vec2(inPos.xy*2 -1);
position = position * pushConstants.myValue;
gl_Position = vec4(position, 0.5, 1.0);
vec4 pos = ubo.model * vec4(inPos, 1.0);
outNormal = mat3(inverse(transpose(ubo.model))) * inNormal;
}
Binary file not shown.
@@ -1,56 +0,0 @@
#version 450
layout (binding = 1) uniform sampler2D samplerColor;
layout (binding = 2) uniform sampler2D samplerColor_ex;
layout (location = 0) in vec2 inUV;
layout (location = 1) in vec3 inNormal;
layout (location = 0) out vec4 outFragColor;
void main()
{
vec4 color = texture(samplerColor, inUV);
vec4 color_ex = texture(samplerColor_ex, inUV);
vec3 N = normalize(inNormal);
// 计算与 (0,0,1) 的点乘
float ndot = dot(N, vec3(0.0, 0.0, -1.0));
// 保证结果 >= 0
ndot = max(ndot, 0.0);
// 重新映射ndot值,让中间2/3部分进行融合
// 当ndot在[0.166, 0.833]范围内时进行混合,两端保持不变
float blendFactor;
if (ndot < 0.0) {
blendFactor = 0.0; // 完全使用color_ex
} else if (ndot > 0.1) {
blendFactor = 1.0; // 完全使用color
} else {
// 在中间2/3部分进行平滑过渡
blendFactor = (ndot - 0.0) / (1 - 0);
}
// 使用smoothstep创建中间2/3的融合区域
// 参数说明:smoothstep(edge0, edge1, x)
// 当x < edge0时返回0,当x > edge1时返回1,在中间时平滑过渡
//float blendFactor = smoothstep(0.166, 0.833, ndot);
// vec4 blendedColor = mix(color_ex, color, ndot);
// outFragColor = blendedColor;
if (ndot < 0.3){
outFragColor = color_ex;
}
else
{
outFragColor = color;
}
// outFragColor = vec4(1, 0, 0, 1);
}
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 139 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

+9 -272
View File
@@ -3,7 +3,7 @@
#include <game-activity/native_app_glue/android_native_app_glue.h> #include <game-activity/native_app_glue/android_native_app_glue.h>
#include <game-activity/GameActivity.h> #include <game-activity/GameActivity.h>
#include "AndroidOut.h" #include "AndroidOut.h"
#include "FaceApp.h" #include "Application.h"
#include <android/asset_manager.h> #include <android/asset_manager.h>
#include <chrono> #include <chrono>
#include <thread> #include <thread>
@@ -12,12 +12,9 @@ using namespace std;
extern "C" { extern "C" {
android_app* g_android_app = nullptr; android_app* g_android_app = nullptr;
FaceApp* g_Application = nullptr; Application* g_Application = nullptr;
AAssetManager* g_assetManager = nullptr; AAssetManager* g_assetManager = nullptr;
jobject g_callback = nullptr;
jobject g_callbackAnimationFinished = nullptr;
void handle_cmd(android_app *pApp, int32_t cmd) { void handle_cmd(android_app *pApp, int32_t cmd) {
switch (cmd) { switch (cmd) {
case APP_CMD_INIT_WINDOW: case APP_CMD_INIT_WINDOW:
@@ -32,22 +29,18 @@ void handle_cmd(android_app *pApp, int32_t cmd) {
} }
} }
const int ArgLen = 128*1024;
char g_InitArgString[ArgLen] = {0};
void android_main(struct android_app *pApp) { void android_main(struct android_app *pApp) {
aout << "Welcome to android_main" << std::endl; aout << "Welcome to android_main" << std::endl;
g_android_app = pApp; g_android_app = pApp;
g_assetManager = pApp->activity->assetManager; g_assetManager = pApp->activity->assetManager;
FaceApp application; Application application;
g_Application = &application; g_Application = &application;
application.SetInitArg(g_InitArgString);
pApp->onAppCmd = handle_cmd; pApp->onAppCmd = handle_cmd;
long long last_update_time = 0;
android_app_set_motion_event_filter(pApp, nullptr); android_app_set_motion_event_filter(pApp, nullptr);
long long _lastDrawFrameTime = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
do { do {
auto start_time = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count(); auto ms = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
// Process all pending events before running game logic. // Process all pending events before running game logic.
bool done = false; bool done = false;
while (!done) { while (!done) {
@@ -75,267 +68,11 @@ void android_main(struct android_app *pApp) {
} }
if(application.isInited()) if(application.isInited())
{ {
auto frameTime = (start_time - _lastDrawFrameTime); application.drawFrame();
_lastDrawFrameTime = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
application.drawFrame(frameTime);
}
auto end_time = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
auto frameTime = end_time - last_update_time;
last_update_time = end_time;
auto function_time = (end_time - start_time);
//aout << "function_time:" << function_time << " fps:" << (1000/frameTime) << std::endl;
if(function_time < 35)
{
this_thread::sleep_for(chrono::milliseconds((35-function_time)));
} }
auto end_ms = chrono::duration_cast<chrono::milliseconds>(chrono::system_clock::now().time_since_epoch()).count();
this_thread::sleep_for(chrono::milliseconds((end_ms-ms)));
} while (!pApp->destroyRequested); } while (!pApp->destroyRequested);
application.cleanup(); application.cleanup();
} }
} }
extern void TextureLoadProcessWithVulkan(uint8_t* data, int width, int height, int rowStride, size_t dataSize);
extern void ReceiveFacePoint(float* pos, int count, int width, int height);
void processWithVulkan(uint8_t* data, int width, int height, int format,
int rowStride, size_t dataSize) {
TextureLoadProcessWithVulkan(data, width, height, rowStride, dataSize);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_processImageNative(JNIEnv *env, jobject thiz, jobject buffer,
jint width, jint height, jint format,
jint row_stride, jint pixel_stride,
jint rotation) {
// TODO: implement processImageNative()
uint8_t* imageData = static_cast<uint8_t*>(env->GetDirectBufferAddress(buffer));
jlong capacity = env->GetDirectBufferCapacity(buffer);
if (imageData == nullptr) {
return;
}
// 在这里将图像数据传递给 Vulkan
// 创建 Vulkan 图像或更新现有图像
processWithVulkan(imageData, width, height, format, row_stride, capacity);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_passDataToNative(JNIEnv *env, jobject thiz, jobject buffer,
jint point_count, jint width, jint height) {
// TODO: implement passDataToNative()
float* pos = static_cast<float*>(env->GetDirectBufferAddress(buffer));
if (pos == nullptr) {
// 处理错误
return;
}
// 或者直接将指针传递给Vulkan
ReceiveFacePoint(pos, point_count, width, height);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_SetCppInitArg(JNIEnv *env, jobject thiz, jstring json) {
// TODO: implement SetCppInitArg()
const char *nativeString = env->GetStringUTFChars(json, nullptr);
jsize len = env->GetStringUTFLength(json);
if(len > ArgLen)
{
aout << "ArgLen to long:" << len << std::endl;
return;
}
memcpy(g_InitArgString, nativeString, len);
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_StopRunning(JNIEnv *env, jobject thiz) {
g_Application->_running = false;
}
JavaVM* g_jvm = nullptr;
// 添加 JNI_OnLoad 函数
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
g_jvm = vm; // 保存 JavaVM 指针,供其他线程使用
return JNI_VERSION_1_6;
}
void CppCallback(const string& motion_type)
{
JNIEnv* env = nullptr;
bool needDetach = false;
// 获取当前线程的 JNIEnv
JavaVM* vm = g_jvm; // 你需要提前保存 JavaVM* 到全局变量 g_jvm
int status = vm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (status == JNI_EDETACHED) {
// 当前线程未 attach,需 attach
if (vm->AttachCurrentThread(&env, nullptr) != 0) {
return;
}
needDetach = true;
} else if (status != JNI_OK) {
return;
}
if (g_callback == nullptr) {
if (needDetach) vm->DetachCurrentThread();
return;
}
// 1. 获取 CallbackInterface 的 class
jclass callbackClass = env->GetObjectClass(g_callback);
if (callbackClass == nullptr) {
if (needDetach) vm->DetachCurrentThread();
return;
}
// 2. 获取 OnLoadActionFinished 方法 ID(注意方法名大小写必须一致!)
jmethodID methodId = env->GetMethodID(callbackClass, "OnLoadActionFinished", "(Ljava/lang/String;)V");
if (methodId == nullptr) {
env->ExceptionDescribe(); // 打印异常
env->ExceptionClear();
if (needDetach) vm->DetachCurrentThread();
return;
}
// 3. 构造 jstring 参数
jstring jResult = env->NewStringUTF(motion_type.c_str());
// 4. 调用 Java 回调
env->CallVoidMethod(g_callback, methodId, jResult);
// 5. 检查是否抛出异常
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
// 6. 释放局部引用(可选,但推荐)
env->DeleteLocalRef(jResult);
env->DeleteLocalRef(callbackClass);
// 7. 如果是临时 attach 的线程,要 detach
if (needDetach) {
vm->DetachCurrentThread();
}
}
void CppAnimationFinishedCallback()
{
JNIEnv* env = nullptr;
bool needDetach = false;
// 获取当前线程的 JNIEnv
JavaVM* vm = g_jvm; // 你需要提前保存 JavaVM* 到全局变量 g_jvm
int status = vm->GetEnv((void**)&env, JNI_VERSION_1_6);
if (status == JNI_EDETACHED) {
// 当前线程未 attach,需 attach
if (vm->AttachCurrentThread(&env, nullptr) != 0) {
return;
}
needDetach = true;
} else if (status != JNI_OK) {
return;
}
if (g_callbackAnimationFinished == nullptr) {
if (needDetach) vm->DetachCurrentThread();
return;
}
// 1. 获取 CallbackInterface 的 class
jclass callbackClass = env->GetObjectClass(g_callbackAnimationFinished);
if (callbackClass == nullptr) {
if (needDetach) vm->DetachCurrentThread();
return;
}
// 2. 获取 OnLoadActionFinished 方法 ID(注意方法名大小写必须一致!)
jmethodID methodId = env->GetMethodID(callbackClass, "OnAnimationFinished", "()V");
if (methodId == nullptr) {
env->ExceptionDescribe(); // 打印异常
env->ExceptionClear();
if (needDetach) vm->DetachCurrentThread();
return;
}
// 4. 调用 Java 回调
env->CallVoidMethod(g_callbackAnimationFinished, methodId);
// 5. 检查是否抛出异常
if (env->ExceptionCheck()) {
env->ExceptionDescribe();
env->ExceptionClear();
}
env->DeleteLocalRef(callbackClass);
// 7. 如果是临时 attach 的线程,要 detach
if (needDetach) {
vm->DetachCurrentThread();
}
}
extern "C"
JNIEXPORT jstring JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_PreReadAction(JNIEnv *env, jobject thiz, jstring motion,
jobject callback) {
// 清理旧的全局引用
if (g_callback != nullptr) {
env->DeleteGlobalRef(g_callback);
g_callback = nullptr;
}
// 保存新的回调
if (callback != nullptr) {
g_callback = env->NewGlobalRef(callback);
} else {
g_callback = nullptr;
}
const char *nativeString = env->GetStringUTFChars(motion, nullptr);
jsize len = env->GetStringUTFLength(motion);
if(len > ArgLen)
{
aout << "ArgLen to long:" << len << std::endl;
}
std::string ret = g_Application->preReadyMotion(nativeString, CppCallback);
return env->NewStringUTF(ret.c_str());
}
extern "C"
JNIEXPORT void JNICALL
Java_com_hmwl_face_1sdk_FaceActivity_ChangeMotionCpp(JNIEnv *env, jobject thiz, jstring json,
jobject callback, jboolean loop) {
// TODO: implement ChangeMotionCpp()
const char *nativeString = env->GetStringUTFChars(json, nullptr);
jsize len = env->GetStringUTFLength(json);
if(len > ArgLen)
{
aout << "ArgLen to long:" << len << std::endl;
return;
}
// 保存新的回调
if (callback != nullptr) {
g_callbackAnimationFinished = env->NewGlobalRef(callback);
} else {
g_callbackAnimationFinished = nullptr;
}
if(g_Application->isInited())
{
g_Application->changeMotion(nativeString, CppAnimationFinishedCallback, loop);
}
}
@@ -1,315 +0,0 @@
package com.hmwl.face_sdk;
import android.Manifest;
import android.content.pm.PackageManager;
import android.os.Bundle;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import androidx.annotation.NonNull;
import androidx.camera.core.AspectRatio;
import androidx.camera.core.CameraSelector;
import androidx.camera.core.ImageAnalysis;
import androidx.camera.core.ImageProxy;
import androidx.camera.lifecycle.ProcessCameraProvider;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;
import com.google.androidgamesdk.GameActivity;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.mediapipe.tasks.components.containers.NormalizedLandmark;
import com.google.mediapipe.tasks.vision.core.RunningMode;
import com.google.mediapipe.tasks.vision.facelandmarker.FaceLandmarkerResult;
import org.jetbrains.annotations.NotNull;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.LandmarkerListener {
private static final String TAG = "FaceActivity";
static {
System.loadLibrary("face_sdk");
}
private ProcessCameraProvider cameraProvider;
private void initCamera(){
backgroundExecutor = Executors.newSingleThreadExecutor();
if (hasCameraPermission()) {
startCamera();
} else {
requestCameraPermission();
}
}
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_CAMERA_PERMISSION) {
// 检查权限是否被授予
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
// 用户授予了权限,启动相机
startCamera();
} else {
requestCameraPermission();
}
}
}
private void startCamera() {
ListenableFuture<ProcessCameraProvider> cameraProviderFuture =
ProcessCameraProvider.getInstance(this);
cameraProviderFuture.addListener(() -> {
try {
cameraProvider = cameraProviderFuture.get();
CameraSelector cameraSelector = new CameraSelector.Builder()
.requireLensFacing(CameraSelector.LENS_FACING_BACK)
.build();
imageAnalyzer = new ImageAnalysis.Builder()
.setTargetAspectRatio(AspectRatio.RATIO_4_3)
.setBackpressureStrategy(ImageAnalysis.STRATEGY_KEEP_ONLY_LATEST)
.setOutputImageFormat(ImageAnalysis.OUTPUT_IMAGE_FORMAT_RGBA_8888)
.build();
imageAnalyzer.setAnalyzer(backgroundExecutor, new ImageAnalysis.Analyzer() {
private int frameCount = 0;
@Override
public void analyze(@NonNull ImageProxy image) {
frameCount++;
try {
processImageForVulkan(image);
if(frameCount %3 == 0)
{
detectFace(image);
}
else
{
image.close();
}
} finally {
//image.close(); // 确保在这里关闭
//Log.d("Camera", "Image closed, ready for next frame");
}
}
});
cameraProvider.bindToLifecycle(this, cameraSelector, imageAnalyzer);
} catch (ExecutionException | InterruptedException e) {
Log.e("MainActivity", "Error starting camera: " + e.getMessage());
}
}, ContextCompat.getMainExecutor(this));
}
private void processImageForVulkan(ImageProxy image) {
// 获取图像信息
int width = image.getWidth();
int height = image.getHeight();
int format = image.getFormat();
// 获取图像数据平面
ImageProxy.PlaneProxy[] planes = image.getPlanes();
// 对于 RGBA_8888 格式,通常只有一个平面
if (planes.length > 0) {
ImageProxy.PlaneProxy plane = planes[0];
ByteBuffer buffer = plane.getBuffer();
int rowStride = plane.getRowStride();
int pixelStride = plane.getPixelStride();
// 调用 Native 方法处理图像
processImageNative(buffer, width, height, format,
rowStride, pixelStride, image.getImageInfo().getRotationDegrees());
}
}
public void Stop(){
StopRunning();
}
private native void StopRunning();
// Native 方法
private native void processImageNative(ByteBuffer buffer, int width, int height,
int format, int rowStride, int pixelStride,
int rotation);
private void detectFace(ImageProxy imageProxy) {
faceLandmarkerHelper.detectLiveStream(
imageProxy,false
);
}
private boolean hasCameraPermission() {
return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
== PackageManager.PERMISSION_GRANTED;
}
private void requestCameraPermission() {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
REQUEST_CAMERA_PERMISSION);
}
private static final int REQUEST_CAMERA_PERMISSION = 1001;
ImageAnalysis imageAnalyzer;
ExecutorService backgroundExecutor;
FaceLandmarkerHelper faceLandmarkerHelper;
@Override
protected void onCreate(Bundle savedInstanceState){
super.onCreate(savedInstanceState);
initCamera();
backgroundExecutor.execute(new Runnable() {
@Override
public void run() {
faceLandmarkerHelper = new FaceLandmarkerHelper(
0.5f,
0.5f,
0.5f,
1,
RunningMode.LIVE_STREAM,
FaceActivity.this,
FaceActivity.this
);
}
});
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUi();
}
}
private void hideSystemUi() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
);
}
@Override
public void onError(@NotNull String error, int errorCode) {
}
private ByteBuffer nativeBuffer = null;
float[] points = new float[480 * 3];
public class Vector {
public float x, y, z;
public Vector(float x, float y, float z) {
this.x = x;
this.y = y;
this.z = z;
}
}
public float z_rate = -1.0f;
@Override
public void onResults(FaceLandmarkerHelper.@NotNull ResultBundle resultBundle) {
FaceLandmarkerResult faceLandmarkerResult = resultBundle.getResult();
int height = resultBundle.getInputImageHeight();
int width = resultBundle.getInputImageWidth();
int bufferSize = 480 * 3 * 4;
if(nativeBuffer == null)
{
// 创建直接ByteBuffer(在native内存中)
nativeBuffer = ByteBuffer.allocateDirect(bufferSize);
nativeBuffer.order(ByteOrder.nativeOrder());
}
long start_time = System.currentTimeMillis();
int index = 0;
// Iterate through each detected face
for (List<NormalizedLandmark> faceLandmarks : faceLandmarkerResult.faceLandmarks()) {
//should be 1
int arrayIndex = 0;
for (NormalizedLandmark p : faceLandmarks)
{
//sb.append("[");
points[arrayIndex++] = p.x();
//sb.append(""+p.x()+",");
points[arrayIndex++] = p.y();
//sb.append(""+p.y()+",");
points[arrayIndex++] = p.z() * z_rate;
index++;
}
}
FloatBuffer floatBuffer = nativeBuffer.asFloatBuffer();
floatBuffer.put(points);
floatBuffer.position(0);
long cur_time = System.currentTimeMillis();
Log.i("TimeLatency","Result Data ProcessTime:" + (cur_time-start_time));
passDataToNative(nativeBuffer, index, width, height);
Log.i("TimeLatency","passDataToNative ProcessTime:" + (System.currentTimeMillis() - cur_time));
}
public native void passDataToNative(ByteBuffer buffer, int pointCount, int width, int height);
protected native void SetCppInitArg(String json);
protected void SetInitArg(String json)
{
SetCppInitArg(json);
}
public interface CallbackInterface {
void OnLoadActionFinished(String result);
}
public interface AnimationFinishedCallbackInterface {
void OnAnimationFinished();
}
protected native String PreReadAction(String motion, CallbackInterface callback);
protected String PreLoadAction(String json, CallbackInterface callback){
return PreReadAction(json, callback);
}
protected native void ChangeMotionCpp(String json, AnimationFinishedCallbackInterface callback, boolean loop);
protected void ChangeMotion(String json, AnimationFinishedCallbackInterface callback, boolean loop){
Log.i("FaceActivity", "ChangeState:" + json);
ChangeMotionCpp(json, callback, loop);
}
// 添加这个缺失的方法
@Override
public void onEmpty() {
// 当没有检测到人脸时的处理逻辑
//Log.d(TAG, "No face detected in the current frame");
}
}
@@ -1,326 +0,0 @@
package com.hmwl.face_sdk
import android.content.Context
import android.graphics.Bitmap
import android.graphics.Matrix
import android.os.SystemClock
import android.util.Log
import androidx.annotation.VisibleForTesting
import androidx.camera.core.ImageProxy
import com.google.mediapipe.framework.image.BitmapImageBuilder
import com.google.mediapipe.framework.image.MPImage
import com.google.mediapipe.tasks.core.BaseOptions
import com.google.mediapipe.tasks.core.Delegate
import com.google.mediapipe.tasks.vision.core.RunningMode
import com.google.mediapipe.tasks.vision.facelandmarker.FaceLandmarker
import com.google.mediapipe.tasks.vision.facelandmarker.FaceLandmarkerResult
class FaceLandmarkerHelper(
var minFaceDetectionConfidence: Float = DEFAULT_FACE_DETECTION_CONFIDENCE,
var minFaceTrackingConfidence: Float = DEFAULT_FACE_TRACKING_CONFIDENCE,
var minFacePresenceConfidence: Float = DEFAULT_FACE_PRESENCE_CONFIDENCE,
var maxNumFaces: Int = DEFAULT_NUM_FACES,
var runningMode: RunningMode = RunningMode.LIVE_STREAM,
val context: Context,
// this listener is only used when running in RunningMode.LIVE_STREAM
val faceLandmarkerHelperListener: LandmarkerListener? = null
) {
// For this example this needs to be a var so it can be reset on changes.
// If the Face Landmarker will not change, a lazy val would be preferable.
private var faceLandmarker: FaceLandmarker? = null
init {
setupFaceLandmarker()
}
fun clearFaceLandmarker() {
faceLandmarker?.close()
faceLandmarker = null
}
// Return running status of FaceLandmarkerHelper
fun isClose(): Boolean {
return faceLandmarker == null
}
fun setupFaceLandmarker() {
// Set general face landmarker options
val baseOptionBuilder = BaseOptions.builder()
// Use the specified hardware for running the model. Default to CPU
baseOptionBuilder.setDelegate(Delegate.GPU)
baseOptionBuilder.setModelAssetPath(MP_FACE_LANDMARKER_TASK)
// Check if runningMode is consistent with faceLandmarkerHelperListener
when (runningMode) {
RunningMode.LIVE_STREAM -> {
if (faceLandmarkerHelperListener == null) {
throw IllegalStateException(
"faceLandmarkerHelperListener must be set when runningMode is LIVE_STREAM."
)
}
}
else -> {
// no-op
}
}
minFaceDetectionConfidence = 0.1f;
minFaceTrackingConfidence = 0.1f;
minFacePresenceConfidence = 0.1f;
try {
val baseOptions = baseOptionBuilder.build()
// Create an option builder with base options and specific
// options only use for Face Landmarker.
val optionsBuilder =
FaceLandmarker.FaceLandmarkerOptions.builder()
.setBaseOptions(baseOptions)
.setMinFaceDetectionConfidence(minFaceDetectionConfidence)
.setMinTrackingConfidence(minFaceTrackingConfidence)
.setMinFacePresenceConfidence(minFacePresenceConfidence)
.setNumFaces(maxNumFaces)
.setOutputFaceBlendshapes(false)
.setOutputFacialTransformationMatrixes(false)
.setRunningMode(runningMode)
// The ResultListener and ErrorListener only use for LIVE_STREAM mode.
if (runningMode == RunningMode.LIVE_STREAM) {
optionsBuilder
.setResultListener(this::returnLivestreamResult)
.setErrorListener(this::returnLivestreamError)
}
val options = optionsBuilder.build()
faceLandmarker =
FaceLandmarker.createFromOptions(context, options)
} catch (e: IllegalStateException) {
faceLandmarkerHelperListener?.onError(
"Face Landmarker failed to initialize. See error logs for " +
"details"
)
Log.e(
TAG, "MediaPipe failed to load the task with error: " + e
.message
)
} catch (e: RuntimeException) {
// This occurs if the model being used does not support GPU
faceLandmarkerHelperListener?.onError(
"Face Landmarker failed to initialize. See error logs for " +
"details", GPU_ERROR
)
Log.e(
TAG,
"Face Landmarker failed to load model with error: " + e.message
)
}
}
private var frameId: Long = 0
// 简化的延时跟踪
private val frameTimings = mutableMapOf<Long, FrameTiming>()
private var lastFpsUpdateTime: Long = 0
private var frameCount: Int = 0
private var currentFps: Double = 0.0
// 内部数据类用于存储时间信息
private data class FrameTiming(
var captureTime: Long = 0,
var preprocessStartTime: Long = 0,
var preprocessEndTime: Long = 0,
var detectionStartTime: Long = 0
)
// 辅助方法:记录帧时间信息
private fun recordFrameTiming(frameId: Long, block: (FrameTiming) -> Unit) {
val timing = frameTimings.getOrPut(frameId) { FrameTiming() }
block(timing)
}
// 辅助方法:更新FPS计算
private fun updateFps() {
frameCount++
val currentTime = SystemClock.uptimeMillis()
if (lastFpsUpdateTime == 0L) {
lastFpsUpdateTime = currentTime
return
}
val timeDiff = currentTime - lastFpsUpdateTime
if (timeDiff >= 1000) { // 每秒更新一次FPS
currentFps = frameCount * 1000.0 / timeDiff
frameCount = 0
lastFpsUpdateTime = currentTime
}
}
// 辅助方法:清理旧的时间记录
private fun cleanupOldTimings(currentFrameId: Long) {
val framesToRemove = frameTimings.keys.filter { it < currentFrameId - 10 }
framesToRemove.forEach { frameTimings.remove(it) }
}
// Convert the ImageProxy to MP Image and feed it to FacelandmakerHelper.
fun detectLiveStream(
imageProxy: ImageProxy,
isFrontCamera: Boolean
) {
if (runningMode != RunningMode.LIVE_STREAM) {
throw IllegalArgumentException(
"Attempting to call detectLiveStream" +
" while not using RunningMode.LIVE_STREAM"
)
}
val frameTime = SystemClock.uptimeMillis()
val currentFrameId = frameId++
val captureTime = SystemClock.uptimeMillis()
// 记录捕获时间
recordFrameTiming(currentFrameId) {
it.captureTime = captureTime
it.preprocessStartTime = SystemClock.uptimeMillis()
}
// Copy out RGB bits from the frame to a bitmap buffer
val bitmapBuffer =
Bitmap.createBitmap(
imageProxy.width,
imageProxy.height,
Bitmap.Config.ARGB_8888
)
imageProxy.use { bitmapBuffer.copyPixelsFromBuffer(imageProxy.planes[0].buffer) }
imageProxy.close()
val matrix = Matrix().apply {
// Rotate the frame received from the camera to be in the same direction as it'll be shown
postRotate(imageProxy.imageInfo.rotationDegrees.toFloat())
// flip image if user use front camera
if (isFrontCamera) {
postScale(
-1f,
1f,
imageProxy.width.toFloat(),
imageProxy.height.toFloat()
)
}
}
val rotatedBitmap = Bitmap.createBitmap(
bitmapBuffer, (640-480)/2, 0, bitmapBuffer.height, bitmapBuffer.height,
matrix, true
)
//val bitmap = BitmapFactory.decodeFile("/sdcard/Android/data/com.khronos.vulkan_samples/files/assets/face480.png")
//val mpImage = BitmapImageBuilder(bitmap).build()
// Convert the input Bitmap object to an MPImage object to run inference
val mpImage = BitmapImageBuilder(rotatedBitmap).build()
detectAsync(mpImage, frameTime)
}
// Run face face landmark using MediaPipe Face Landmarker API
@VisibleForTesting
fun detectAsync(mpImage: MPImage, frameTime: Long) {
faceLandmarker?.detectAsync(mpImage, frameTime)
// As we're using running mode LIVE_STREAM, the landmark result will
// be returned in returnLivestreamResult function
}
// Return the landmark result to this FaceLandmarkerHelper's caller
private fun returnLivestreamResult(
result: FaceLandmarkerResult,
input: MPImage
) {
val resultTime = SystemClock.uptimeMillis()
val frameId = result.timestampMs()
if( result.faceLandmarks().size > 0 ) {
// 计算各种延时
// val timings = frameTimings[frameId]
// if (timings != null) {
// val totalLatency = resultTime - timings.captureTime
// val preprocessLatency = timings.preprocessEndTime - timings.preprocessStartTime
// val detectionLatency = resultTime - timings.detectionStartTime
// val captureToDetectionLatency = timings.detectionStartTime - timings.captureTime
//
// Log.i("TimeLatency",
// "总延时: ${totalLatency}ms | " +
// "预处理: ${preprocessLatency}ms | " +
// "检测: ${detectionLatency}ms | " +
// "捕获到检测: ${captureToDetectionLatency}ms | " +
// "FPS: ${String.format("%.1f", currentFps)}"
// )
//
// val finishTimeMs = SystemClock.uptimeMillis()
// val inferenceTime = finishTimeMs - result.timestampMs()
// faceLandmarkerHelperListener?.onResults(
// ResultBundle(
// result,
// inferenceTime, // 主要是检测时间
// input.height,
// input.width,
// )
// )
// } else
//{
val finishTimeMs = SystemClock.uptimeMillis()
val inferenceTime = finishTimeMs - result.timestampMs()
Log.i("TimeLatency",
"总延时: ${inferenceTime}ms | "
)
faceLandmarkerHelperListener?.onResults(
ResultBundle(
result,
inferenceTime,
input.height,
input.width
)
)
//}
}
else {
faceLandmarkerHelperListener?.onEmpty()
}
}
// Return errors thrown during detection to this FaceLandmarkerHelper's
// caller
private fun returnLivestreamError(error: RuntimeException) {
faceLandmarkerHelperListener?.onError(
error.message ?: "An unknown error has occurred"
)
}
companion object {
const val TAG = "FaceLandmarkerHelper"
private const val MP_FACE_LANDMARKER_TASK = "face_landmarker.task"
const val DELEGATE_CPU = 0
const val DELEGATE_GPU = 1
const val DEFAULT_FACE_DETECTION_CONFIDENCE = 0.5F
const val DEFAULT_FACE_TRACKING_CONFIDENCE = 0.5F
const val DEFAULT_FACE_PRESENCE_CONFIDENCE = 0.5F
const val DEFAULT_NUM_FACES = 1
const val OTHER_ERROR = 0
const val GPU_ERROR = 1
}
data class ResultBundle(
val result: FaceLandmarkerResult,
val inferenceTime: Long,
val inputImageHeight: Int,
val inputImageWidth: Int,
)
interface LandmarkerListener {
fun onError(error: String, errorCode: Int = OTHER_ERROR)
fun onResults(resultBundle: ResultBundle)
fun onEmpty() {}
}
}
@@ -1,19 +0,0 @@
package com.hmwl.face_sdk;
import org.json.JSONObject;
public class InitArg {
public int action_fps;
public float zoom;
public String toJson() {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("action_fps", action_fps);
jsonObject.put("zoom", zoom);
return jsonObject.toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
}
@@ -1,36 +0,0 @@
package com.hmwl.face_sdk;
import org.json.JSONArray;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class Motion {
public String type = "no";
public List<String> png_names = new ArrayList<>();
public JSONObject toJsonObject() {
try {
JSONObject jsonObject = new JSONObject();
jsonObject.put("type", type);
JSONArray ja = new JSONArray();
for(int i = 0; i < png_names.size(); ++i){
ja.put(png_names.get(i));
}
jsonObject.put("png_names", ja);
return jsonObject;
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
public String toJson() {
try {
return toJsonObject().toString();
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
};
@@ -0,0 +1,60 @@
package com.hmwl.sample;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.google.androidgamesdk.GameActivity;
public class MainActivity extends GameActivity{
private static final String TAG = "MainActivity";
static {
System.loadLibrary("sample");
}
@Override
public boolean onTouchEvent(MotionEvent event) {
int action = event.getActionMasked();
float x = event.getX();
float y = event.getY();
switch (action) {
case MotionEvent.ACTION_DOWN:
Log.d(TAG, "Java Layer: Touch DOWN at (" + x + ", " + y + ")");
// ✅ 你可以在这里做些事,比如发消息给 C++,或 UI 反馈
break;
case MotionEvent.ACTION_MOVE:
Log.d(TAG, "Java Layer: Touch MOVE");
break;
case MotionEvent.ACTION_UP:
Log.d(TAG, "Java Layer: Touch UP");
break;
}
// ⚠️ 关键:返回 false 才能让事件继续传递给 Native 层(C++)
// 如果返回 true,表示事件已被消费,C++ 层将收不到!
return false;
}
@Override
public void onWindowFocusChanged(boolean hasFocus) {
super.onWindowFocusChanged(hasFocus);
if (hasFocus) {
hideSystemUi();
}
}
private void hideSystemUi() {
View decorView = getWindow().getDecorView();
decorView.setSystemUiVisibility(
View.SYSTEM_UI_FLAG_IMMERSIVE_STICKY
| View.SYSTEM_UI_FLAG_LAYOUT_STABLE
| View.SYSTEM_UI_FLAG_LAYOUT_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_LAYOUT_FULLSCREEN
| View.SYSTEM_UI_FLAG_HIDE_NAVIGATION
| View.SYSTEM_UI_FLAG_FULLSCREEN
);
}
}
Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.3 KiB

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.3 KiB

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

Before

Width:  |  Height:  |  Size: 982 B

After

Width:  |  Height:  |  Size: 982 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 40 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 21 KiB

Before

Width:  |  Height:  |  Size: 5.8 KiB

After

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

Before

Width:  |  Height:  |  Size: 3.8 KiB

After

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 36 KiB

Before

Width:  |  Height:  |  Size: 7.6 KiB

After

Width:  |  Height:  |  Size: 7.6 KiB

@@ -0,0 +1,17 @@
package com.hmwl.sample;
import org.junit.Test;
import static org.junit.Assert.*;
/**
* Example local unit test, which will execute on the development machine (host).
*
* @see <a href="http://d.android.com/tools/testing">Testing documentation</a>
*/
public class ExampleUnitTest {
@Test
public void addition_isCorrect() {
assertEquals(4, 2 + 2);
}
}
+1 -16
View File
@@ -1,19 +1,4 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript {
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:8.3.2'
}
}
plugins { plugins {
alias(libs.plugins.android.application) apply false alias(libs.plugins.android.application) apply false
alias(libs.plugins.android.library) apply false
alias(libs.plugins.kotlin.android) apply false // 添加这行
//alias(libs.plugins.kotlin.android) apply false
//id 'org.jetbrains.kotlin.android' version '2.2.0' apply false
} }
-11
View File
@@ -1,11 +0,0 @@
glslangValidator -V app/src/main/assets/shaders/bg.frag -o app/src/main/assets/shaders/bg.frag.spv
glslangValidator -V app/src/main/assets/shaders/bg.vert -o app/src/main/assets/shaders/bg.vert.spv
glslangValidator -V app/src/main/assets/shaders/texture.frag -o app/src/main/assets/shaders/texture.frag.spv
glslangValidator -V app/src/main/assets/shaders/texture.vert -o app/src/main/assets/shaders/texture.vert.spv
glslangValidator -V app/src/main/assets/shaders/texture_thick.frag -o app/src/main/assets/shaders/texture_thick.frag.spv
glslangValidator -V app/src/main/assets/shaders/texture_thick.vert -o app/src/main/assets/shaders/texture_thick.vert.spv
glslangValidator -V app/src/main/assets/shaders/simple_shader.frag -o app/src/main/assets/shaders/simple_shader.frag.spv
glslangValidator -V app/src/main/assets/shaders/simple_shader.vert -o app/src/main/assets/shaders/simple_shader.vert.spv
-1
View File
@@ -1 +0,0 @@
/build
-86
View File
@@ -1,86 +0,0 @@
plugins {
alias(libs.plugins.android.application)
alias(libs.plugins.kotlin.android)
//alias(libs.plugins.kotlin.android)
}
android {
namespace 'com.inewme.uvmirror'
compileSdk 36
defaultConfig {
applicationId "com.inewme.uvmirror.f20251129"
minSdk 30
targetSdk 36
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
}
buildTypes {
release {
signingConfig signingConfigs.debug
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
compileOptions {
sourceCompatibility JavaVersion.VERSION_17
targetCompatibility JavaVersion.VERSION_17
}
buildFeatures {
compose true
}
composeOptions {
kotlinCompilerExtensionVersion '1.5.1'
}
kotlinOptions {
jvmTarget = '17'
}
// kotlinOptions {
// jvmTarget = '17'
// }
}
dependencies {
implementation libs.appcompat
implementation libs.material
implementation libs.games.activity
implementation libs.core.ktx
implementation libs.androidx.core.ktx
testImplementation libs.junit
androidTestImplementation libs.ext.junit
androidTestImplementation libs.espresso.core
implementation project(':app')
// Jetpack Compose
implementation "androidx.compose.ui:ui:1.5.0"
implementation "androidx.compose.material3:material3:1.0.0"
implementation "androidx.compose.foundation:foundation:1.5.0"
implementation "androidx.compose.runtime:runtime:1.5.0"
implementation "androidx.activity:activity-compose:1.7.2" // ؼṩ setContent
implementation "androidx.compose.ui:ui-tooling:1.5.4"
def camerax_version = '1.4.2'
implementation "androidx.camera:camera-core:$camerax_version"
implementation "androidx.camera:camera-camera2:$camerax_version"
implementation "androidx.camera:camera-lifecycle:$camerax_version"
implementation "androidx.camera:camera-view:$camerax_version"
implementation 'com.google.protobuf:protobuf-javalite:3.21.12'
implementation 'com.google.android.datatransport:transport-runtime:3.1.9'
implementation 'com.google.android.datatransport:transport-backend-cct:3.1.9'
implementation 'com.google.flogger:flogger:0.7.4'
implementation 'com.google.flogger:flogger-system-backend:0.7.4'
implementation 'com.google.guava:guava:31.1-android'
implementation("androidx.lifecycle:lifecycle-runtime-ktx:2.8.7") // 提供 lifecycleScope
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-android:1.9.0")
}
-21
View File
@@ -1,21 +0,0 @@
# Add project specific ProGuard rules here.
# You can control the set of applied configuration files using the
# proguardFiles setting in build.gradle.
#
# For more details, see
# http://developer.android.com/guide/developing/tools/proguard.html
# If your project uses WebView with JS, uncomment the following
# and specify the fully qualified class name to the JavaScript interface
# class:
#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
# public *;
#}
# Uncomment this to preserve the line number information for
# debugging stack traces.
#-keepattributes SourceFile,LineNumberTable
# If you keep the line number information, uncomment this to
# hide the original source file name.
#-renamesourcefileattribute SourceFile
-29
View File
@@ -1,29 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/Theme.Sample" >
<activity
android:name=".MainActivity"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<meta-data
android:name="android.app.lib_name"
android:value="face_sdk" />
</activity>
<activity
android:name=".MakeupActivity"
android:exported="false" />
</application>
</manifest>
Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

Some files were not shown because too many files have changed in this diff Show More