From b52b2985fedf7f9a01fcd97fe8b20555560c483c Mon Sep 17 00:00:00 2001 From: Matthew Date: Sun, 15 Sep 2024 23:30:24 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle | 4 ++ app/src/main/cpp/MicroPhoto.cpp | 32 +++++++++++ app/src/main/cpp/PhoneDevice.cpp | 54 +++++-------------- app/src/main/cpp/PhoneDevice.h | 1 + .../com/xypower/mpapp/MicroPhotoService.java | 33 ++++++++++-- .../com/xypower/mpapp/video/RawActivity.java | 21 +++++++- gradle.properties | 4 +- 7 files changed, 99 insertions(+), 50 deletions(-) diff --git a/app/build.gradle b/app/build.gradle index 587a0dda..085e0326 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -113,6 +113,10 @@ android { exclude 'META-INF/LICENSE-notice.md' exclude 'META-INF/LICENSE.md' + jniLibs { + useLegacyPackaging true + } + } } diff --git a/app/src/main/cpp/MicroPhoto.cpp b/app/src/main/cpp/MicroPhoto.cpp index 20a6a4e9..93bf15f3 100644 --- a/app/src/main/cpp/MicroPhoto.cpp +++ b/app/src/main/cpp/MicroPhoto.cpp @@ -708,6 +708,38 @@ Java_com_xypower_mpapp_MicroPhotoService_getNextScheduleItem( */ +extern "C" JNIEXPORT void JNICALL +Java_com_xypower_mpapp_MicroPhotoService_captureFinished( + JNIEnv* env, + jobject pThis, jlong handler, jboolean photoOrVideo, jboolean result, jobject bitmap, jlong photoId) { + + CTerminal* pTerminal = reinterpret_cast(handler); + if (pTerminal == NULL) + { + return; + } + + IDevice* dev = pTerminal->GetDevice(); + if (dev != NULL) + { + AndroidBitmapInfo info = { 0 }; + int res = AndroidBitmap_getInfo(env, bitmap, &info); + if (res < 0 || info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) + { + } + void* pixels = NULL; + res = AndroidBitmap_lockPixels(env, bitmap, &pixels); + if (res < 0) + { + } + + cv::Mat mat(info.height, info.width, CV_8UC4, pixels); + AndroidBitmap_unlockPixels(env, bitmap); + + ((CPhoneDevice *)dev)->OnCaptureReady(photoOrVideo != JNI_FALSE, result != JNI_FALSE, mat, (unsigned long)photoId); + } +} + extern "C" JNIEXPORT void JNICALL Java_com_xypower_mpapp_MicroPhotoService_recordingFinished( JNIEnv* env, diff --git a/app/src/main/cpp/PhoneDevice.cpp b/app/src/main/cpp/PhoneDevice.cpp index b8014177..1aa5f34d 100644 --- a/app/src/main/cpp/PhoneDevice.cpp +++ b/app/src/main/cpp/PhoneDevice.cpp @@ -1787,56 +1787,26 @@ bool CPhoneDevice::OnImageReady(cv::Mat& mat) return res; } -bool CPhoneDevice::OnVideoReady(bool photoOrVideo, bool result, const char* path, unsigned int photoId) +bool CPhoneDevice::OnCaptureReady(bool photoOrVideo, bool result, cv::Mat& mat, unsigned int photoId) { if (photoOrVideo) { - AImageDecoder* decoder = NULL; - int fd = open(path, O_RDONLY); - if (fd == -1) - { - - } - int result = AImageDecoder_createFromFd(fd, &decoder); - if (result != ANDROID_IMAGE_DECODER_SUCCESS) - { - } - - auto decoder_cleanup = [&decoder] () { - AImageDecoder_delete(decoder); - }; - - const AImageDecoderHeaderInfo* header_info = AImageDecoder_getHeaderInfo(decoder); - int bitmap_format = AImageDecoderHeaderInfo_getAndroidBitmapFormat(header_info); - // This is just for example. I don't want to handle other cases in this - // example, but that should be easy enough to do. - if (bitmap_format != ANDROID_BITMAP_FORMAT_RGBA_8888) + if (result) { - decoder_cleanup(); + OnImageReady(mat); } - - constexpr int kChannels = 4; - int width = AImageDecoderHeaderInfo_getWidth(header_info); - int height = AImageDecoderHeaderInfo_getHeight(header_info); - - size_t stride = AImageDecoder_getMinimumStride(decoder); - - size_t size = stride * height; - std::vector pixels; - pixels.resize(size, 0); - int decode_result = AImageDecoder_decodeImage(decoder, &pixels[0], stride, size); - if (decode_result != ANDROID_IMAGE_DECODER_SUCCESS) + else { - decoder_cleanup(); - return false; + std::vector objs; + TakePhotoCb(result, mPhotoInfo, "", time(NULL), objs); } + } +} - cv::Mat mat(height, width, CV_8UC4, (void*)&pixels[0]); - - OnImageReady(mat); - - decoder_cleanup(); - close(fd); +bool CPhoneDevice::OnVideoReady(bool photoOrVideo, bool result, const char* path, unsigned int photoId) +{ + if (photoOrVideo) + { } else { diff --git a/app/src/main/cpp/PhoneDevice.h b/app/src/main/cpp/PhoneDevice.h index 4e90e371..0be210e9 100644 --- a/app/src/main/cpp/PhoneDevice.h +++ b/app/src/main/cpp/PhoneDevice.h @@ -220,6 +220,7 @@ public: void UpdatePosition(double lon, double lat, double radius, time_t ts); bool OnVideoReady(bool photoOrVideo, bool result, const char* path, unsigned int photoId); + bool OnCaptureReady(bool photoOrVideo, bool result, cv::Mat& mat, unsigned int photoId); void UpdateSignalLevel(int signalLevel); void UpdateTfCardPath(const std::string& tfCardPath) diff --git a/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java b/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java index 21aa2f1b..a22260b8 100644 --- a/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java +++ b/app/src/main/java/com/xypower/mpapp/MicroPhotoService.java @@ -13,6 +13,8 @@ import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; +import android.graphics.Bitmap; +import android.graphics.ImageDecoder; import android.location.Location; import android.location.LocationListener; import android.location.LocationManager; @@ -392,13 +394,33 @@ public class MicroPhotoService extends Service { mService.reloadConfigs(mService.mNativeHandle); } } else if (TextUtils.equals(ACTION_VIDEO_FINISHED, action)) { - boolean photoOrVideo = intent.getBooleanExtra("photoOrVideo", false); - boolean result = intent.getBooleanExtra("result", false); - String path = intent.getStringExtra("path"); - long videoId = intent.getLongExtra("videoId", 0); + final boolean photoOrVideo = intent.getBooleanExtra("photoOrVideo", false); + final boolean result = intent.getBooleanExtra("result", false); + final String path = intent.getStringExtra("path"); + final long videoId = intent.getLongExtra("videoId", 0); Log.i(TAG, "Recording received(" + Long.toString(videoId) + "):" + path); - mService.recordingFinished(mService.mNativeHandle, photoOrVideo, result, path, videoId); + if (photoOrVideo) { + Thread thread = new Thread(new Runnable() { + @Override + public void run() { + Bitmap bm = null; + ImageDecoder.Source src = ImageDecoder.createSource(new File(path)); + try { + bm = ImageDecoder.decodeBitmap(src); + } catch (Exception ex) { + + } + + + } + }); + + thread.start(); + + } else { + mService.recordingFinished(mService.mNativeHandle, photoOrVideo, result, path, videoId); + } } else if (TextUtils.equals(ACTION_STOP, action)) { mService.stopTerminalService(); } else if (TextUtils.equals(ACTION_IMP_PUBKRY, action)) { @@ -1206,6 +1228,7 @@ cellSignalStrengthGsm.getDbm(); protected native void updatePosition(long handler, double lon, double lat, double radius, long ts); protected native boolean uninit(long handler); protected native void recordingFinished(long handler, boolean photoOrVideo, boolean result, String path, long videoId); + protected native void captureFinished(long handler, boolean photoOrVideo, boolean result, Bitmap bm, long videoId); public static native long takePhoto(int channel, int preset, boolean photoOrVideo, String configFilePath, String path); public static native void releaseDeviceHandle(long deviceHandle); public static native boolean sendExternalPhoto(long deviceHandle, String path); diff --git a/app/src/main/java/com/xypower/mpapp/video/RawActivity.java b/app/src/main/java/com/xypower/mpapp/video/RawActivity.java index cc73ab1b..f50ef794 100644 --- a/app/src/main/java/com/xypower/mpapp/video/RawActivity.java +++ b/app/src/main/java/com/xypower/mpapp/video/RawActivity.java @@ -6,6 +6,7 @@ import androidx.localbroadcastmanager.content.LocalBroadcastManager; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.ImageDecoder; import android.os.Looper; import android.os.Message; import android.os.SystemClock; @@ -1300,6 +1301,7 @@ public class RawActivity extends AppCompatActivity { output = new FileOutputStream(mFile); dngCreator.writeImage(output, mImage); + mResult = true; } catch (IOException e) { e.printStackTrace(); @@ -1307,6 +1309,16 @@ public class RawActivity extends AppCompatActivity { mImage.close(); closeOutput(output); } + + if (mResult) { + try { + // ImageDecoder.Source src = ImageDecoder.createSource(mFile); + // Bitmap bm = ImageDecoder.decodeBitmap(src); + } catch (Exception ex) { + + } + + } break; } default: { @@ -1638,7 +1650,14 @@ public class RawActivity extends AppCompatActivity { @Override public void run() { broadcastPhotoFile(saver.getResult(), saver.getPath()); - finish(); + + mMessageHandler.postDelayed(new Runnable() { + @Override + public void run() { + finish(); + } + }, 1000); + } }); diff --git a/gradle.properties b/gradle.properties index 5d441ee5..8cf42ac3 100644 --- a/gradle.properties +++ b/gradle.properties @@ -20,8 +20,8 @@ android.enableJetifier=true BUILD_TOOLS_VERSION=33.0.3 COMPILE_SDK_VERSION=33 -TARGET_SDK_VERSION=30 -COMPILE_MIN_SDK_VERSION=30 +TARGET_SDK_VERSION=28 +COMPILE_MIN_SDK_VERSION=28 opencvsdk=D:/Workspace/deps/opencv-mobile-4.9.0-android # opencvsdk=D:/Workspace/deps/opencv-mobile-3.4.20-android