diff --git a/app/android/AndroidManifest.xml b/app/android/AndroidManifest.xml index 9f5869f..c421afe 100644 --- a/app/android/AndroidManifest.xml +++ b/app/android/AndroidManifest.xml @@ -28,12 +28,15 @@ + + { + private CameraDataCallback callback; + private String errorMessage; + + public FetchCameraDataTask(CameraDataCallback callback) { + this.callback = callback; + } + + @Override + protected CameraData doInBackground(String... urls) { + if (urls.length == 0) { + errorMessage = "URL不能为空"; + return null; + } + + String apiUrl = urls[0]; + HttpURLConnection connection = null; + BufferedReader reader = null; + + try { + URL url = new URL(apiUrl); + connection = (HttpURLConnection) url.openConnection(); + connection.setRequestMethod("GET"); + connection.setConnectTimeout(10000); // 10秒连接超时 + connection.setReadTimeout(10000); // 10秒读取超时 + connection.setRequestProperty("Accept", "application/json"); + + int responseCode = connection.getResponseCode(); + if (responseCode == HttpURLConnection.HTTP_OK) { + InputStream inputStream = connection.getInputStream(); + reader = new BufferedReader(new InputStreamReader(inputStream)); + + StringBuilder response = new StringBuilder(); + String line; + while ((line = reader.readLine()) != null) { + response.append(line); + } + + JSONObject jsonObject = new JSONObject(response.toString()); + return CameraData.fromJson(jsonObject); + } else { + errorMessage = "HTTP请求失败,响应码: " + responseCode; + return null; + } + } catch (Exception e) { + errorMessage = "获取相机数据时发生错误: " + e.getMessage(); + Log.e("CameraDataFetcher", errorMessage, e); + return null; + } finally { + if (connection != null) { + connection.disconnect(); + } + try { + if (reader != null) { + reader.close(); + } + } catch (Exception e) { + Log.e("CameraDataFetcher", "关闭流时出错", e); + } + } + } + + @Override + protected void onPostExecute(CameraData result) { + if (callback != null) { + if (result != null) { + callback.onSuccess(result); + } else { + callback.onError(errorMessage != null ? errorMessage : "未知错误"); + } + } + } + } +} \ No newline at end of file diff --git a/app/android/java/com/khronos/vulkan_samples/FaceLandmarkerHelper.kt b/app/android/java/com/khronos/vulkan_samples/FaceLandmarkerHelper.kt index 71efa9f..a6efedb 100644 --- a/app/android/java/com/khronos/vulkan_samples/FaceLandmarkerHelper.kt +++ b/app/android/java/com/khronos/vulkan_samples/FaceLandmarkerHelper.kt @@ -176,7 +176,7 @@ class FaceLandmarkerHelper( } } val rotatedBitmap = Bitmap.createBitmap( - bitmapBuffer, 0, 0, bitmapBuffer.width, bitmapBuffer.height, + bitmapBuffer, (640-480)/2, 0, bitmapBuffer.height, bitmapBuffer.height, matrix, true ) diff --git a/app/android/java/com/khronos/vulkan_samples/MainActivity.java b/app/android/java/com/khronos/vulkan_samples/MainActivity.java index ec80a9d..8e72ee3 100644 --- a/app/android/java/com/khronos/vulkan_samples/MainActivity.java +++ b/app/android/java/com/khronos/vulkan_samples/MainActivity.java @@ -4,6 +4,8 @@ package com.khronos.vulkan_samples; import android.Manifest; import android.content.pm.PackageManager; import android.os.Bundle; +import android.os.Handler; +import android.os.Looper; import android.util.Log; import android.view.WindowManager; import android.widget.Toast; @@ -33,7 +35,7 @@ import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; -public class MainActivity extends GameActivity implements FaceLandmarkerHelper.LandmarkerListener{ +public class MainActivity extends GameActivity implements FaceLandmarkerHelper.LandmarkerListener, CameraDataFetcher.CameraDataCallback { private ProcessCameraProvider cameraProvider; private void initCamera(){ backgroundExecutor = Executors.newSingleThreadExecutor(); @@ -50,6 +52,9 @@ public class MainActivity extends GameActivity implements FaceLandmarkerHelper.L ); } + private Handler handler = new Handler(Looper.getMainLooper()); + private Runnable cameraDataRunnable; + private static final long INTERVAL = 1000; // 5秒间隔 @Override protected void onCreate(Bundle savedInstanceState) { @@ -87,12 +92,44 @@ public class MainActivity extends GameActivity implements FaceLandmarkerHelper.L } }); + // 初始化Runnable + cameraDataRunnable = new Runnable() { + @Override + public void run() { + fetchCameraData(); + handler.postDelayed(this, INTERVAL); // 再次调度 + } + }; + // 开始周期性调用 + startPeriodicFetching(); Log.i("MainActivity", "onCreate: "); } + boolean canFetch = true; + private void fetchCameraData() { + if(canFetch) + { + CameraDataFetcher.fetchCameraData("http://175.178.100.240:5000/data", MainActivity.this); + canFetch = false; + } + } + private void startPeriodicFetching() { + handler.postDelayed(cameraDataRunnable, INTERVAL); + } + + private void stopPeriodicFetching() { + handler.removeCallbacks(cameraDataRunnable); + } + + @Override + protected void onDestroy() { + super.onDestroy(); + stopPeriodicFetching(); // 避免内存泄漏 + } + private boolean hasCameraPermission() { return ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA) == PackageManager.PERMISSION_GRANTED; @@ -133,12 +170,12 @@ public class MainActivity extends GameActivity implements FaceLandmarkerHelper.L @Override public void analyze(@NonNull ImageProxy image) { try { - Log.d("Camera", "Received image: " + image.getWidth() + "x" + image.getHeight()); + //Log.d("Camera", "Received image: " + image.getWidth() + "x" + image.getHeight()); processImageForVulkan(image); detectFace(image); } finally { //image.close(); // 确保在这里关闭 - Log.d("Camera", "Image closed, ready for next frame"); + //Log.d("Camera", "Image closed, ready for next frame"); } } }); @@ -151,6 +188,7 @@ public class MainActivity extends GameActivity implements FaceLandmarkerHelper.L }, ContextCompat.getMainExecutor(this)); } + private void processImageForVulkan(ImageProxy image) { // 获取图像信息 int width = image.getWidth(); @@ -230,9 +268,6 @@ public class MainActivity extends GameActivity implements FaceLandmarkerHelper.L nativeBuffer.order(ByteOrder.nativeOrder()); } - float offsetX = (640.f-480.f)/640.0f; - offsetX /= 2; - offsetX *= -1; int index = 0; // Iterate through each detected face for (List faceLandmarks : faceLandmarkerResult.faceLandmarks()) { @@ -244,7 +279,7 @@ public class MainActivity extends GameActivity implements FaceLandmarkerHelper.L //Log.i(TAG, "Index" + index + " x:"+p.x() + " y:"+p.y() + " z:"+p.z()); points[arrayIndex++] = p.x(); points[arrayIndex++] = p.y(); - points[arrayIndex++] = p.z(); + points[arrayIndex++] = p.z() * z_rate; index++; } } @@ -255,5 +290,26 @@ public class MainActivity extends GameActivity implements FaceLandmarkerHelper.L floatBuffer.position(0); passDataToNative(nativeBuffer, index, width, height); } + + public float z_rate = 1.0f; + public native void passDataToNative(ByteBuffer buffer, int pointCount, int width, int height); + public native void upDateCameraData(float fov, float x, float y, float z, float sx, float sy, float sz, float rotx, float roty, float rotz, float camx, float camy, float camz); + + @Override + public void onSuccess(CameraDataFetcher.CameraData data) { + z_rate = data.z_rate; + upDateCameraData(data.fov, data.x, data.y, data.z, data.sx, data.sy, data.sz, + data.rotx, data.roty, data.rotz, + data.camx, data.camy, data.camz + ); + canFetch = true; + Log.e(TAG, "GetCameraData " + data.toString()); + } + + @Override + public void onError(String errorMessage) { + Log.e(TAG, "GetCameraData Error"); + canFetch = true; + } } \ No newline at end of file diff --git a/app/android/res/xml/network_security_config.xml b/app/android/res/xml/network_security_config.xml new file mode 100644 index 0000000..9d9b41a --- /dev/null +++ b/app/android/res/xml/network_security_config.xml @@ -0,0 +1,10 @@ + + + + + + + + + + \ No newline at end of file