36张图片打包
@@ -12,7 +12,7 @@ using namespace std;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
android_app* g_android_app = nullptr;
|
android_app* g_android_app = nullptr;
|
||||||
Application* g_Application = nullptr;
|
FaceApp* g_Application = nullptr;
|
||||||
AAssetManager* g_assetManager = nullptr;
|
AAssetManager* g_assetManager = nullptr;
|
||||||
|
|
||||||
void handle_cmd(android_app *pApp, int32_t cmd) {
|
void handle_cmd(android_app *pApp, int32_t cmd) {
|
||||||
@@ -143,4 +143,20 @@ Java_com_hmwl_face_1sdk_FaceActivity_SetCppInitArg(JNIEnv *env, jobject thiz, js
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
memcpy(g_InitArgString, nativeString, len);
|
memcpy(g_InitArgString, nativeString, len);
|
||||||
|
}
|
||||||
|
extern "C"
|
||||||
|
JNIEXPORT void JNICALL
|
||||||
|
Java_com_hmwl_face_1sdk_FaceActivity_ChangeStateCpp(JNIEnv *env, jobject thiz, jstring json) {
|
||||||
|
// TODO: implement ChangeStateCpp()
|
||||||
|
const char *nativeString = env->GetStringUTFChars(json, nullptr);
|
||||||
|
jsize len = env->GetStringUTFLength(json);
|
||||||
|
if(len > ArgLen)
|
||||||
|
{
|
||||||
|
aout << "ArgLen to long:" << len << std::endl;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if(g_Application->isInited())
|
||||||
|
{
|
||||||
|
g_Application->changeMotion(nativeString);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -171,31 +171,6 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@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
|
@Override
|
||||||
public void onWindowFocusChanged(boolean hasFocus) {
|
public void onWindowFocusChanged(boolean hasFocus) {
|
||||||
super.onWindowFocusChanged(hasFocus);
|
super.onWindowFocusChanged(hasFocus);
|
||||||
@@ -290,7 +265,10 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L
|
|||||||
{
|
{
|
||||||
SetCppInitArg(json);
|
SetCppInitArg(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected native void ChangeStateCpp(String json);
|
||||||
protected void ChangeState(String json){
|
protected void ChangeState(String json){
|
||||||
Log.i("FaceActivity", "ChangeState:" + json);
|
Log.i("FaceActivity", "ChangeState:" + json);
|
||||||
|
ChangeStateCpp(json);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2,11 +2,11 @@ package com.hmwl.face_sdk;
|
|||||||
import org.json.JSONObject;
|
import org.json.JSONObject;
|
||||||
|
|
||||||
public class Motion {
|
public class Motion {
|
||||||
public String type;
|
public String type = "no";
|
||||||
public String technique;
|
public String technique = "no";
|
||||||
public String step;
|
public String step = "no";
|
||||||
public String show_type;
|
public String show_type = "no";
|
||||||
public String png_name;
|
public String png_name = "no";
|
||||||
public int png_num;
|
public int png_num;
|
||||||
|
|
||||||
public JSONObject toJsonObject() {
|
public JSONObject toJsonObject() {
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ android {
|
|||||||
compileSdk 36
|
compileSdk 36
|
||||||
|
|
||||||
defaultConfig {
|
defaultConfig {
|
||||||
applicationId "com.hmwl.f20251028"
|
applicationId "com.hmwl.f20251030"
|
||||||
minSdk 30
|
minSdk 30
|
||||||
targetSdk 36
|
targetSdk 36
|
||||||
versionCode 1
|
versionCode 1
|
||||||
|
|||||||
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 20 KiB |
|
Before Width: | Height: | Size: 26 KiB |
|
Before Width: | Height: | Size: 22 KiB |
|
Before Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 28 KiB |
|
Before Width: | Height: | Size: 24 KiB |
|
Before Width: | Height: | Size: 32 KiB |
|
Before Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 4.9 KiB |
|
After Width: | Height: | Size: 8.6 KiB |
|
After Width: | Height: | Size: 6.3 KiB |
|
After Width: | Height: | Size: 3.3 KiB |
|
After Width: | Height: | Size: 6.5 KiB |
|
After Width: | Height: | Size: 8.2 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 5.5 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 3.8 KiB |
|
After Width: | Height: | Size: 5.0 KiB |
|
After Width: | Height: | Size: 4.3 KiB |
|
After Width: | Height: | Size: 15 KiB |
|
After Width: | Height: | Size: 8.0 KiB |
|
After Width: | Height: | Size: 6.6 KiB |
|
After Width: | Height: | Size: 8.7 KiB |
|
After Width: | Height: | Size: 3.2 KiB |
|
After Width: | Height: | Size: 7.4 KiB |
|
After Width: | Height: | Size: 9.1 KiB |
|
After Width: | Height: | Size: 5.1 KiB |
|
After Width: | Height: | Size: 7.0 KiB |
|
After Width: | Height: | Size: 6.2 KiB |
|
After Width: | Height: | Size: 5.6 KiB |
|
After Width: | Height: | Size: 4.5 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 5.7 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 7.6 KiB |
|
After Width: | Height: | Size: 5.4 KiB |
|
After Width: | Height: | Size: 4.0 KiB |
|
After Width: | Height: | Size: 4.2 KiB |
|
After Width: | Height: | Size: 4.8 KiB |
@@ -0,0 +1,34 @@
|
|||||||
|
[
|
||||||
|
"11.png",
|
||||||
|
"12.png",
|
||||||
|
"13.png",
|
||||||
|
"14.png",
|
||||||
|
"21.png",
|
||||||
|
"23.png",
|
||||||
|
"24.png",
|
||||||
|
"25.png",
|
||||||
|
"26.png",
|
||||||
|
"27.png",
|
||||||
|
"32.png",
|
||||||
|
"37.png",
|
||||||
|
"4.png",
|
||||||
|
"40.png",
|
||||||
|
"41.png",
|
||||||
|
"45.png",
|
||||||
|
"48.png",
|
||||||
|
"49.png",
|
||||||
|
"5.png",
|
||||||
|
"53.png",
|
||||||
|
"56.png",
|
||||||
|
"59.png",
|
||||||
|
"6.png",
|
||||||
|
"62.png",
|
||||||
|
"65.png",
|
||||||
|
"68.png",
|
||||||
|
"7.png",
|
||||||
|
"71.png",
|
||||||
|
"76.png",
|
||||||
|
"77.png",
|
||||||
|
"78.png",
|
||||||
|
"81.png"
|
||||||
|
]
|
||||||
@@ -1,13 +1,30 @@
|
|||||||
package com.hmwl.example;
|
package com.hmwl.example;
|
||||||
|
|
||||||
|
import android.content.Context;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.view.MotionEvent;
|
||||||
|
import android.widget.Toast;
|
||||||
|
|
||||||
import com.hmwl.face_sdk.InitArg;
|
import com.hmwl.face_sdk.InitArg;
|
||||||
import com.hmwl.face_sdk.Motion;
|
import com.hmwl.face_sdk.Motion;
|
||||||
|
|
||||||
|
|
||||||
import com.hmwl.face_sdk.FaceActivity;
|
import com.hmwl.face_sdk.FaceActivity;
|
||||||
public class MainActivity extends FaceActivity{
|
|
||||||
|
import org.json.JSONArray;
|
||||||
|
import org.json.JSONException;
|
||||||
|
import org.json.JSONObject;
|
||||||
|
|
||||||
|
import java.io.BufferedReader;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.io.InputStreamReader;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
public class MainActivity extends FaceActivity
|
||||||
|
{
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onCreate(Bundle savedInstanceState)
|
protected void onCreate(Bundle savedInstanceState)
|
||||||
@@ -17,7 +34,7 @@ public class MainActivity extends FaceActivity{
|
|||||||
motion.technique = "基础上妆";
|
motion.technique = "基础上妆";
|
||||||
motion.step = "2按压";
|
motion.step = "2按压";
|
||||||
motion.show_type = "方向示意图";
|
motion.show_type = "方向示意图";
|
||||||
motion.png_name = "test";
|
motion.png_name = "4.png";
|
||||||
motion.png_num = 1;
|
motion.png_num = 1;
|
||||||
|
|
||||||
InitArg initArg = new InitArg();
|
InitArg initArg = new InitArg();
|
||||||
@@ -25,7 +42,82 @@ public class MainActivity extends FaceActivity{
|
|||||||
initArg.zoom = 1.5f;
|
initArg.zoom = 1.5f;
|
||||||
initArg.motion = motion;
|
initArg.motion = motion;
|
||||||
SetInitArg(initArg.toJson());
|
SetInitArg(initArg.toJson());
|
||||||
super.onCreate(savedInstanceState);
|
|
||||||
|
|
||||||
|
|
||||||
|
super.onCreate(savedInstanceState);
|
||||||
|
FaceInit(this);
|
||||||
|
Toast.makeText(this, "4.png", Toast.LENGTH_LONG).show();
|
||||||
|
}
|
||||||
|
|
||||||
|
String GetCurMotionState(int index)
|
||||||
|
{
|
||||||
|
Motion motion = new Motion();
|
||||||
|
motion.png_name = pngFilenames.get(index);
|
||||||
|
motion.png_num = 1;
|
||||||
|
return motion.toJson();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean onTouchEvent(MotionEvent event) {
|
||||||
|
// 获取触控动作
|
||||||
|
int action = event.getAction();
|
||||||
|
|
||||||
|
switch (action) {
|
||||||
|
case MotionEvent.ACTION_DOWN:
|
||||||
|
// 手指按下
|
||||||
|
Log.d("TouchEvent", "手指按下 - X: " + event.getX() + ", Y: " + event.getY());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_MOVE:
|
||||||
|
// 手指移动
|
||||||
|
Log.d("TouchEvent", "手指移动 - X: " + event.getX() + ", Y: " + event.getY());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MotionEvent.ACTION_UP:
|
||||||
|
// 手指抬起
|
||||||
|
Log.d("TouchEvent", "手指抬起");
|
||||||
|
curIndex++;
|
||||||
|
if(curIndex > pngFilenames.size()-1)
|
||||||
|
{
|
||||||
|
curIndex = 0;
|
||||||
|
}
|
||||||
|
ChangeState(GetCurMotionState(curIndex));
|
||||||
|
Toast.makeText(this, pngFilenames.get(curIndex), Toast.LENGTH_LONG).show();
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true; // 表示已处理该事件
|
||||||
|
}
|
||||||
|
|
||||||
|
List<String> pngFilenames = null;
|
||||||
|
int curIndex = 0;
|
||||||
|
private void FaceInit(Context context){
|
||||||
|
pngFilenames = readPngFilenamesFromAssets(context, "pic/png_filenames.json");
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<String> readPngFilenamesFromAssets(Context context, String filename) {
|
||||||
|
List<String> pngFilenames = new ArrayList<>();
|
||||||
|
|
||||||
|
try {
|
||||||
|
InputStream is = context.getAssets().open(filename);
|
||||||
|
BufferedReader reader = new BufferedReader(new InputStreamReader(is));
|
||||||
|
StringBuilder stringBuilder = new StringBuilder();
|
||||||
|
String line;
|
||||||
|
while ((line = reader.readLine()) != null) {
|
||||||
|
stringBuilder.append(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
JSONArray jsonArray = new JSONArray(stringBuilder.toString());
|
||||||
|
for (int i = 0; i < jsonArray.length(); i++) {
|
||||||
|
pngFilenames.add(jsonArray.getString(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
reader.close();
|
||||||
|
is.close();
|
||||||
|
} catch (Exception e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
return pngFilenames;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
<resources>
|
<resources>
|
||||||
<string name="app_name">f20251028</string>
|
<string name="app_name">f20251030</string>
|
||||||
</resources>
|
</resources>
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
import os
|
||||||
|
import json
|
||||||
|
|
||||||
|
def simple_collect_png_filenames(folder_path, output_file="../example/src/main/assets/pic/png_filenames.json"):
|
||||||
|
"""
|
||||||
|
简化版的PNG文件名收集器(不遍历子文件夹)
|
||||||
|
"""
|
||||||
|
# 检查文件夹是否存在
|
||||||
|
if not os.path.exists(folder_path):
|
||||||
|
print(f"错误:文件夹 '{folder_path}' 不存在")
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 获取文件夹中的所有文件
|
||||||
|
try:
|
||||||
|
all_files = os.listdir(folder_path)
|
||||||
|
except PermissionError:
|
||||||
|
print(f"错误:没有权限访问文件夹 '{folder_path}'")
|
||||||
|
return []
|
||||||
|
|
||||||
|
# 筛选PNG文件
|
||||||
|
png_filenames = []
|
||||||
|
for file in all_files:
|
||||||
|
file_path = os.path.join(folder_path, file)
|
||||||
|
if os.path.isfile(file_path) and file.lower().endswith('.png'):
|
||||||
|
png_filenames.append(file)
|
||||||
|
|
||||||
|
# 按文件名排序
|
||||||
|
png_filenames.sort()
|
||||||
|
|
||||||
|
# 保存到JSON文件
|
||||||
|
try:
|
||||||
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
|
json.dump(png_filenames, f, ensure_ascii=False, indent=2)
|
||||||
|
print(f"找到 {len(png_filenames)} 个PNG文件,文件名已保存到 {output_file}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"保存文件时出错: {e}")
|
||||||
|
|
||||||
|
# 显示找到的文件
|
||||||
|
if png_filenames:
|
||||||
|
print("\n找到的PNG文件:")
|
||||||
|
for filename in png_filenames:
|
||||||
|
print(f" - {filename}")
|
||||||
|
|
||||||
|
return png_filenames
|
||||||
|
|
||||||
|
# 使用方法
|
||||||
|
if __name__ == "__main__":
|
||||||
|
# 指定要遍历的文件夹
|
||||||
|
folder_to_scan = '../example/src/main/assets/pic'
|
||||||
|
|
||||||
|
simple_collect_png_filenames(folder_to_scan)
|
||||||
@@ -732,7 +732,7 @@ void FaceApp::initVulkan()
|
|||||||
loadTexture("demo0_ex.png", m_texs_ex[i], true);
|
loadTexture("demo0_ex.png", m_texs_ex[i], true);
|
||||||
}
|
}
|
||||||
|
|
||||||
loadTexture("out.png", tex_bg, false);
|
loadTexture("out.png", tex_bg, true);
|
||||||
createVertexBuffer();
|
createVertexBuffer();
|
||||||
createUniformBuffer();
|
createUniformBuffer();
|
||||||
setup_descriptor_pool();
|
setup_descriptor_pool();
|
||||||
@@ -1137,19 +1137,27 @@ void FaceApp::SetInitArg(const char* arg)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void FaceApp::changeMotion(const char* json)
|
||||||
|
{
|
||||||
|
Motion motion = json::parse(json);
|
||||||
|
changeMotion(motion);
|
||||||
|
}
|
||||||
|
|
||||||
void FaceApp::changeMotion(Motion& motion)
|
void FaceApp::changeMotion(Motion& motion)
|
||||||
{
|
{
|
||||||
if (_curMotion.getMotionId() == motion.getMotionId())
|
if (_curMotion.getMotionId() == motion.getMotionId())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
_curMotion = _initArg.motion;
|
_curMotion = motion;
|
||||||
for (int i = 0; i < _curMotion.png_num; ++i)
|
for (int i = 0; i < _curMotion.png_num; ++i)
|
||||||
{
|
{
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
//string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
||||||
string path_name = path + "/" + _curMotion.png_name + std::to_string(i) + ".png";
|
string path = "pic";
|
||||||
|
string path_name = path + "/" + _curMotion.png_name;// +std::to_string(i) + ".png";
|
||||||
loadTextureExample(UTF8ToWideString(path_name), m_texs[i], true);
|
loadTextureExample(UTF8ToWideString(path_name), m_texs[i], true);
|
||||||
if (kThick)
|
if (kThick)
|
||||||
{
|
{
|
||||||
@@ -1157,8 +1165,9 @@ void FaceApp::changeMotion(Motion& motion)
|
|||||||
loadTextureExample(UTF8ToWideString(path_name_ex), m_texs_ex[i], true);
|
loadTextureExample(UTF8ToWideString(path_name_ex), m_texs_ex[i], true);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
//string path = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
||||||
string path_name = path + "/" + _curMotion.png_name + std::to_string(i) + ".png";
|
string path = "pic";
|
||||||
|
string path_name = path + "/" + _curMotion.png_name;// +std::to_string(i) + ".png";
|
||||||
loadTexture(path_name, m_texs[i], true);
|
loadTexture(path_name, m_texs[i], true);
|
||||||
if (kThick)
|
if (kThick)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ struct Motion {
|
|||||||
string png_name;
|
string png_name;
|
||||||
int png_num;
|
int png_num;
|
||||||
string getMotionId() {
|
string getMotionId() {
|
||||||
return type + technique + step + show_type;
|
return type + technique + step + show_type + png_name;
|
||||||
}
|
}
|
||||||
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, type, technique, step, show_type, png_name, png_num)
|
NLOHMANN_DEFINE_TYPE_INTRUSIVE(Motion, type, technique, step, show_type, png_name, png_num)
|
||||||
};
|
};
|
||||||
@@ -104,7 +104,7 @@ private:
|
|||||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||||
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||||
vector<VkDescriptorSet> m_descriptor_sets;
|
vector<VkDescriptorSet> m_descriptor_sets;
|
||||||
const int kMaxTexture = 20;
|
const int kMaxTexture = 2;
|
||||||
vector<Texture> m_texs;
|
vector<Texture> m_texs;
|
||||||
vector<Texture> m_texs_ex;
|
vector<Texture> m_texs_ex;
|
||||||
|
|
||||||
@@ -137,8 +137,10 @@ private:
|
|||||||
VkDescriptorSetLayout m_descriptorSetLayout_bg = VK_NULL_HANDLE;
|
VkDescriptorSetLayout m_descriptorSetLayout_bg = VK_NULL_HANDLE;
|
||||||
VkDescriptorSet m_descriptor_set_bg = VK_NULL_HANDLE;
|
VkDescriptorSet m_descriptor_set_bg = VK_NULL_HANDLE;
|
||||||
|
|
||||||
void changeMotion(Motion& motion);
|
|
||||||
public:
|
public:
|
||||||
|
void changeMotion(const char* json);
|
||||||
|
void changeMotion(Motion& motion);
|
||||||
InitArg _initArg;
|
InitArg _initArg;
|
||||||
Motion _curMotion;
|
Motion _curMotion;
|
||||||
int _curTexIndex = 0;
|
int _curTexIndex = 0;
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ int main() {
|
|||||||
motion.technique = "基础上妆";
|
motion.technique = "基础上妆";
|
||||||
motion.step = "2按压";
|
motion.step = "2按压";
|
||||||
motion.show_type = "方向示意图";
|
motion.show_type = "方向示意图";
|
||||||
motion.png_name = "test";
|
motion.png_name = "4.png";
|
||||||
motion.png_num = 1;
|
motion.png_num = 1;
|
||||||
#
|
#
|
||||||
|
|
||||||
|
|||||||