36张图片打包
@@ -12,7 +12,7 @@ using namespace std;
|
||||
extern "C" {
|
||||
|
||||
android_app* g_android_app = nullptr;
|
||||
Application* g_Application = nullptr;
|
||||
FaceApp* g_Application = nullptr;
|
||||
AAssetManager* g_assetManager = nullptr;
|
||||
|
||||
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;
|
||||
}
|
||||
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
|
||||
public void onWindowFocusChanged(boolean hasFocus) {
|
||||
super.onWindowFocusChanged(hasFocus);
|
||||
@@ -290,7 +265,10 @@ public class FaceActivity extends GameActivity implements FaceLandmarkerHelper.L
|
||||
{
|
||||
SetCppInitArg(json);
|
||||
}
|
||||
|
||||
protected native void ChangeStateCpp(String json);
|
||||
protected void ChangeState(String json){
|
||||
Log.i("FaceActivity", "ChangeState:" + json);
|
||||
ChangeStateCpp(json);
|
||||
}
|
||||
}
|
||||
@@ -2,11 +2,11 @@ package com.hmwl.face_sdk;
|
||||
import org.json.JSONObject;
|
||||
|
||||
public class Motion {
|
||||
public String type;
|
||||
public String technique;
|
||||
public String step;
|
||||
public String show_type;
|
||||
public String png_name;
|
||||
public String type = "no";
|
||||
public String technique = "no";
|
||||
public String step = "no";
|
||||
public String show_type = "no";
|
||||
public String png_name = "no";
|
||||
public int png_num;
|
||||
|
||||
public JSONObject toJsonObject() {
|
||||
|
||||
@@ -7,7 +7,7 @@ android {
|
||||
compileSdk 36
|
||||
|
||||
defaultConfig {
|
||||
applicationId "com.hmwl.f20251028"
|
||||
applicationId "com.hmwl.f20251030"
|
||||
minSdk 30
|
||||
targetSdk 36
|
||||
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;
|
||||
|
||||
import android.content.Context;
|
||||
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.Motion;
|
||||
|
||||
|
||||
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
|
||||
protected void onCreate(Bundle savedInstanceState)
|
||||
@@ -17,7 +34,7 @@ public class MainActivity extends FaceActivity{
|
||||
motion.technique = "基础上妆";
|
||||
motion.step = "2按压";
|
||||
motion.show_type = "方向示意图";
|
||||
motion.png_name = "test";
|
||||
motion.png_name = "4.png";
|
||||
motion.png_num = 1;
|
||||
|
||||
InitArg initArg = new InitArg();
|
||||
@@ -25,7 +42,82 @@ public class MainActivity extends FaceActivity{
|
||||
initArg.zoom = 1.5f;
|
||||
initArg.motion = motion;
|
||||
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>
|
||||
<string name="app_name">f20251028</string>
|
||||
<string name="app_name">f20251030</string>
|
||||
</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("out.png", tex_bg, false);
|
||||
loadTexture("out.png", tex_bg, true);
|
||||
createVertexBuffer();
|
||||
createUniformBuffer();
|
||||
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)
|
||||
{
|
||||
if (_curMotion.getMotionId() == motion.getMotionId())
|
||||
{
|
||||
return;
|
||||
}
|
||||
_curMotion = _initArg.motion;
|
||||
_curMotion = motion;
|
||||
for (int i = 0; i < _curMotion.png_num; ++i)
|
||||
{
|
||||
|
||||
#ifdef _WIN32
|
||||
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 = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
||||
string path = "pic";
|
||||
string path_name = path + "/" + _curMotion.png_name;// +std::to_string(i) + ".png";
|
||||
loadTextureExample(UTF8ToWideString(path_name), m_texs[i], true);
|
||||
if (kThick)
|
||||
{
|
||||
@@ -1157,8 +1165,9 @@ void FaceApp::changeMotion(Motion& motion)
|
||||
loadTextureExample(UTF8ToWideString(path_name_ex), m_texs_ex[i], true);
|
||||
}
|
||||
#else
|
||||
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 = _curMotion.type + "/" + _curMotion.technique + "/" + _curMotion.step + "/" + _curMotion.show_type;
|
||||
string path = "pic";
|
||||
string path_name = path + "/" + _curMotion.png_name;// +std::to_string(i) + ".png";
|
||||
loadTexture(path_name, m_texs[i], true);
|
||||
if (kThick)
|
||||
{
|
||||
|
||||
@@ -19,7 +19,7 @@ struct Motion {
|
||||
string png_name;
|
||||
int png_num;
|
||||
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)
|
||||
};
|
||||
@@ -104,7 +104,7 @@ private:
|
||||
VkPipelineLayout m_pipelineLayout = VK_NULL_HANDLE;
|
||||
VkDescriptorSetLayout m_descriptorSetLayout = VK_NULL_HANDLE;
|
||||
vector<VkDescriptorSet> m_descriptor_sets;
|
||||
const int kMaxTexture = 20;
|
||||
const int kMaxTexture = 2;
|
||||
vector<Texture> m_texs;
|
||||
vector<Texture> m_texs_ex;
|
||||
|
||||
@@ -137,8 +137,10 @@ private:
|
||||
VkDescriptorSetLayout m_descriptorSetLayout_bg = VK_NULL_HANDLE;
|
||||
VkDescriptorSet m_descriptor_set_bg = VK_NULL_HANDLE;
|
||||
|
||||
void changeMotion(Motion& motion);
|
||||
|
||||
public:
|
||||
void changeMotion(const char* json);
|
||||
void changeMotion(Motion& motion);
|
||||
InitArg _initArg;
|
||||
Motion _curMotion;
|
||||
int _curTexIndex = 0;
|
||||
|
||||
@@ -53,7 +53,7 @@ int main() {
|
||||
motion.technique = "基础上妆";
|
||||
motion.step = "2按压";
|
||||
motion.show_type = "方向示意图";
|
||||
motion.png_name = "test";
|
||||
motion.png_name = "4.png";
|
||||
motion.png_num = 1;
|
||||
#
|
||||
|
||||
|
||||