diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index c56cbf0..ca7b652 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -21,7 +21,9 @@
android:supportsRtl="true"
android:theme="@style/Theme.MpPreview"
android:requestLegacyExternalStorage="true"
+ android:largeHeap="true"
tools:targetApi="30">
+
diff --git a/app/src/main/cpp/MpPreview.cpp b/app/src/main/cpp/MpPreview.cpp
index 2c99c35..3aa1fd5 100644
--- a/app/src/main/cpp/MpPreview.cpp
+++ b/app/src/main/cpp/MpPreview.cpp
@@ -434,7 +434,7 @@ Java_com_xypower_mppreview_Camera2RawFragment_makeHdr3(JNIEnv *env, jclass clazz
if ((ANDROID_BITMAP_FLAGS_IS_HARDWARE & bmpInfo.flags) == ANDROID_BITMAP_FLAGS_IS_HARDWARE)
{
-// AHardwareBuffer* hardwareBuffer = NULL;
+ AHardwareBuffer* hardwareBuffer = NULL;
//// result = AndroidBitmap_getHardwareBuffer(env, bitmaps[idx], &hardwareBuffer);
//
// void* outVirtualAddress = NULL;
@@ -452,7 +452,7 @@ Java_com_xypower_mppreview_Camera2RawFragment_makeHdr3(JNIEnv *env, jclass clazz
cv::Mat tmp(bmpInfo.height, bmpInfo.width, CV_8UC4, outAddress);
tmp.copyTo(images[idx]);
AndroidBitmap_unlockPixels(env, bitmaps[idx]);
- tmp.release();
+// tmp.release();
}
//convert RGB to BGR
@@ -497,4 +497,40 @@ JNIEXPORT jboolean JNICALL
Java_com_xypower_mppreview_Camera2RawFragment_decodeDng(JNIEnv *env, jclass clazz,
jobject byte_buffer, jstring output_path) {
// TODO: implement decodeDng()
+}
+extern "C"
+JNIEXPORT jboolean JNICALL
+Java_com_xypower_mppreview_MainActivity_test(JNIEnv *env, jclass clazz) {
+ // TODO: implement test()
+
+ std::vector images;
+ {
+ cv::Mat img1 = cv::imread("/sdcard/DCIM/YUV_20250315_184325_959_.bmp");
+ images.push_back(img1);
+ }
+ {
+ cv::Mat img2 = cv::imread("/sdcard/DCIM/YUV_20250315_184337_167_.bmp");
+ images.push_back(img2);
+ }
+
+ std::vector times;
+ times.push_back((double)(1190000) / 1000000000.0);
+ times.push_back((double)(8330000) / 1000000000.0);
+
+ ALOGI("Start MakeHDR3");
+ cv::Mat rgb;
+ makeHdr(times, images, rgb);
+ ALOGI("End MakeHDR3");
+
+ std::string fileName = "";
+ std::vector params;
+ params.push_back(cv::IMWRITE_JPEG_QUALITY);
+ params.push_back(100);
+ if (cv::imwrite(fileName.c_str(), rgb, params))
+ {
+ rgb.release();
+
+ ALOGI("End HDR3");
+ }
+
}
\ No newline at end of file
diff --git a/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java b/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java
index 29270a6..8588843 100644
--- a/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java
+++ b/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java
@@ -41,6 +41,7 @@ import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.os.SystemClock;
+import android.renderscript.RenderScript;
import android.util.Log;
import android.util.Range;
import android.util.Rational;
@@ -64,6 +65,7 @@ import com.xypower.mppreview.bean.Contants;
import com.xypower.mppreview.bean.PngPhotoBean;
import com.xypower.mppreview.interfaces.CompleteCallback;
import com.xypower.mppreview.utils.HdrUtil;
+import com.xypower.mppreview.utils.ImageConverterUtil;
import com.xypower.mppreview.widget.ErrorDialog;
@@ -489,7 +491,7 @@ public class Camera2RawFragment extends Fragment {
@Override
public void onCaptureCompleted(CameraCaptureSession session, CaptureRequest request, TotalCaptureResult result) {
int requestId = (int) request.getTag();
- ImageSaverBuilder jpegBuilder;
+// ImageSaverBuilder jpegBuilder;
ImageSaverBuilder rawBuilder;
ImageSaverBuilder yuvBuilder;
StringBuilder sb = new StringBuilder();
@@ -497,7 +499,7 @@ public class Camera2RawFragment extends Fragment {
synchronized (mCameraStateLock) {
// jpegBuilder = mJpegResultQueue.get(requestId);
rawBuilder = mRawResultQueue.get(requestId);
- yuvBuilder = mRawResultQueue.get(requestId);
+ yuvBuilder = mYuvResultQueue.get(requestId);
// if (jpegBuilder != null) {
// jpegBuilder.setResult(result);
@@ -532,7 +534,8 @@ public class Camera2RawFragment extends Fragment {
public void onCaptureFailed(CameraCaptureSession session, CaptureRequest request, CaptureFailure failure) {
int requestId = (int) request.getTag();
synchronized (mCameraStateLock) {
- mJpegResultQueue.remove(requestId);
+// mJpegResultQueue.remove(requestId);
+ mYuvResultQueue.remove(requestId);
mRawResultQueue.remove(requestId);
finishedCaptureLocked();
}
@@ -803,7 +806,8 @@ public class Camera2RawFragment extends Fragment {
}
try {
// Find a CameraDevice that supports RAW captures, and configure state.
- for (String cameraId : manager.getCameraIdList()) {
+ String[] cameraIdList = manager.getCameraIdList();
+ for (String cameraId : cameraIdList) {
CameraCharacteristics characteristics = manager.getCameraCharacteristics(cameraId);
// We only use a camera that supports RAW in this sample.
@@ -814,7 +818,9 @@ public class Camera2RawFragment extends Fragment {
// For still image captures, we use the largest available size.
Size[] outputSizes = map.getOutputSizes(ImageFormat.YUV_420_888);
// Size largestJpeg = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.JPEG)), new CompareSizesByArea());
- Size largestYuv = Collections.max(Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888)), new CompareSizesByArea());
+ List coll = Arrays.asList(map.getOutputSizes(ImageFormat.YUV_420_888));
+// Size largestYuv = Collections.max(coll, new CompareSizesByArea());
+ Size largestYuv = coll.get(1);
outputSizes = map.getOutputSizes(ImageFormat.RAW_SENSOR);
@@ -1001,7 +1007,7 @@ public class Camera2RawFragment extends Fragment {
mPreviewRequestBuilder.addTarget(surface);
// Here, we create a CameraCaptureSession for camera preview.
- mCameraDevice.createCaptureSession(Arrays.asList(surface, mRawImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() {
+ mCameraDevice.createCaptureSession(Arrays.asList(surface, mYuvImageReader.get().getSurface(),mRawImageReader.get().getSurface()), new CameraCaptureSession.StateCallback() {
@Override
public void onConfigured(CameraCaptureSession cameraCaptureSession) {
synchronized (mCameraStateLock) {
@@ -1244,8 +1250,9 @@ public class Camera2RawFragment extends Fragment {
// This is the CaptureRequest.Builder that we use to take a picture.
final CaptureRequest.Builder captureBuilder = mCameraDevice.createCaptureRequest(CameraDevice.TEMPLATE_STILL_CAPTURE);
- captureBuilder.addTarget(mJpegImageReader.get().getSurface());
+// captureBuilder.addTarget(mJpegImageReader.get().getSurface());
captureBuilder.addTarget(mRawImageReader.get().getSurface());
+ captureBuilder.addTarget(mYuvImageReader.get().getSurface());
// Use the same AE and AF modes as the preview.
setup3AControlsLocked(captureBuilder);
@@ -1287,7 +1294,8 @@ public class Camera2RawFragment extends Fragment {
runnable = new ImageSaver.ImagePairRunnable(imagePair) {
@Override
public void run() {
- final List images = imagePair.getImages();
+// final List images = imagePair.getImages();
+ List images = imagePair.getMImages();
final String outputPath = "/sdcard/DCIM/";
new Thread(new Runnable() {
@Override
@@ -1295,12 +1303,48 @@ public class Camera2RawFragment extends Fragment {
if (images.size() != 2) {
return;
}
- ImageSaver.ImageInfo img1 = images.get(0);
- ImageSaver.ImageInfo img2 = images.get(1);
+// Image img1 = images.get(0);
+// Image img2 = images.get(1);
+// ImageConverterUtil imageConverterUtil1 = new ImageConverterUtil();
+// RenderScript rs = RenderScript.create(getContext());
+// imageConverterUtil1.saveYuvImageFromImageReader(img1, rs,"");
+// Log.d("开始Hdr处理", "strat");
+// ImageConverterUtil imageConverterUtil2 = new ImageConverterUtil();
+//// RenderScript rs2 = RenderScript.create(getContext());
+// imageConverterUtil1.saveYuvImageFromImageReader(img2, rs,"");
+//// String hdrOutputPath = outputPath + "HDR_" + generateTimestamp() + ".bmp";
+//// RenderScript rs = RenderScript.create(getContext());
+//// ImageConverterUtil imageConverterUtil1 = new ImageConverterUtil();
+////// boolean b = makeHdr3(img1.exposureTime, img1.bitmap, img1.length, img2.exposureTime, img2.bitmap, img2.length, hdrOutputPath);
+//// Bitmap img11 = imageConverterUtil1.imageYuvToBitmap(img1, rs);
+//// ImageConverterUtil imageConverterUtil2 = new ImageConverterUtil();
+//// Bitmap img12 = imageConverterUtil2.imageYuvToBitmap(img2, rs);
+//// boolean b = makeHdr3(1000, bitmap, 0,2000, bitmap1, 0, hdrOutputPath);
+
+
+
+
+ Image img1 = images.get(0);
+ Image img2 = images.get(1);
+ ImageConverterUtil imageConverterUtil1 = new ImageConverterUtil();
+ RenderScript rs = RenderScript.create(getContext());
+ Bitmap bitmap = imageConverterUtil1.imageYuvToBitmap(img1, rs);
Log.d("开始Hdr处理", "strat");
+ ImageConverterUtil imageConverterUtil2 = new ImageConverterUtil();
+// RenderScript rs2 = RenderScript.create(getContext());
+ Bitmap bitmap1 = imageConverterUtil1.imageYuvToBitmap(img2, rs);
+
+ Log.d("HDR测试", "Hdr");
String hdrOutputPath = outputPath + "HDR_" + generateTimestamp() + ".bmp";
- boolean b = makeHdr3(img1.exposureTime, img1.bitmap, img1.length, img2.exposureTime, img2.bitmap, img2.length, hdrOutputPath);
+// RenderScript rs = RenderScript.create(getContext());
+// ImageConverterUtil imageConverterUtil1 = new ImageConverterUtil();
+//// boolean b = makeHdr3(img1.exposureTime, img1.bitmap, img1.length, img2.exposureTime, img2.bitmap, img2.length, hdrOutputPath);
+// Bitmap img11 = imageConverterUtil1.imageYuvToBitmap(img1, rs);
+// ImageConverterUtil imageConverterUtil2 = new ImageConverterUtil();
+// Bitmap img12 = imageConverterUtil2.imageYuvToBitmap(img2, rs);
+ boolean b = makeHdr3(1000, bitmap, 0,2000, bitmap1, 0, hdrOutputPath);
+ Log.d("HDR测试2", "Hdr");
// Mat mat1 = new Mat();
// Mat mat2 = new Mat();
@@ -1311,27 +1355,27 @@ public class Camera2RawFragment extends Fragment {
// Mat[] mats = {mat1, mat2};
// float[] floats = {img1.exposureTime,img2.exposureTime};
// HdrUtil.createHDR(mats, floats,Hdrmat,hdrOutputPath);
- img1.bitmap.recycle();
- img2.bitmap.recycle();
+// img1.bitmap.recycle();
+// img2.bitmap.recycle();
img1 = null;
img2 = null;
images.clear();
Log.d("结束Hdr处理", "end");
- if (b) {
- getActivity().runOnUiThread(new Runnable() {
- @Override
- public void run() {
- // 在主线程中执行UI更新
- // ...
- takepic.setVisibility(View.VISIBLE);
- rorpic.clearAnimation();
- rorpic.setVisibility(View.GONE);
- showToast("HDR拍摄成功");
- }
- });
-
- }
+// if (b) {
+// getActivity().runOnUiThread(new Runnable() {
+// @Override
+// public void run() {
+// // 在主线程中执行UI更新
+// // ...
+// takepic.setVisibility(View.VISIBLE);
+// rorpic.clearAnimation();
+// rorpic.setVisibility(View.GONE);
+// showToast("HDR拍摄成功");
+// }
+// });
+//
+// }
}
}).start();
@@ -1340,7 +1384,7 @@ public class Camera2RawFragment extends Fragment {
imagePair.setRunnable(runnable);
- for (int idx = 0; idx < 2; idx++) {
+ for (int idx = 0; idx < 1; idx++) {
// Set request tag to easily track results in callbacks.
captureBuilder.setTag(mRequestCounter.getAndIncrement());
@@ -1350,7 +1394,7 @@ public class Camera2RawFragment extends Fragment {
captureBuilder.set(CaptureRequest.CONTROL_AE_MODE, CaptureRequest.CONTROL_AE_MODE_OFF);
captureBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 0);
if (exposureTime > 0) {
- v = exposureTime;
+ v = (long) ((long) exposureTime * (7));
captureBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, v);
}
if (sensitivity > 0) {
@@ -1363,7 +1407,7 @@ public class Camera2RawFragment extends Fragment {
captureBuilder.set(CaptureRequest.CONTROL_AE_EXPOSURE_COMPENSATION, 2);
if (exposureTime > 0) {
if (pic1 <= 0) {
- v = exposureTime * DEFAULT_COMPATATION;
+ v = exposureTime *7;
captureBuilder.set(CaptureRequest.SENSOR_EXPOSURE_TIME, v);
} else {
v = exposureTime * pic1;
@@ -1377,8 +1421,9 @@ public class Camera2RawFragment extends Fragment {
CaptureRequest request = captureBuilder.build();
- ImageSaverBuilder jpegBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);
+// ImageSaverBuilder jpegBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);
ImageSaverBuilder rawBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);//保存拍照参数
+
rawBuilder.setImagePair(imagePair);
rawBuilder.setCallback(new CompleteCallback() {
@Override
@@ -1387,8 +1432,24 @@ public class Camera2RawFragment extends Fragment {
}
});
rawBuilder.setList(mlist);
- mJpegResultQueue.put((int) request.getTag(), jpegBuilder);
+
+
+ ImageSaverBuilder yuvBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);//保存拍照参数
+
+ yuvBuilder.setImagePair(imagePair);
+ yuvBuilder.setCallback(new CompleteCallback() {
+ @Override
+ public void onResult() {
+ showToast("HDR拍摄成功");
+ }
+ });
+ yuvBuilder.setList(mlist);
+
+// mJpegResultQueue.put((int) request.getTag(), jpegBuilder);
mRawResultQueue.put((int) request.getTag(), rawBuilder);
+ mYuvResultQueue.put((int) request.getTag(), yuvBuilder);
+
+
requests.add(request);
}
mCaptureSession.captureBurst(requests, mCaptureCallback, mBackgroundHandler);
@@ -1407,11 +1468,13 @@ public class Camera2RawFragment extends Fragment {
// Create an ImageSaverBuilder in which to collect results, and add it to the queue
// of active requests.
- ImageSaverBuilder jpegBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);
+// ImageSaverBuilder jpegBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);
ImageSaverBuilder rawBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);
+ ImageSaverBuilder yuvBuilder = new ImageSaverBuilder(activity).setCharacteristics(mCharacteristics);
- mJpegResultQueue.put((int) request.getTag(), jpegBuilder);
+// mJpegResultQueue.put((int) request.getTag(), jpegBuilder);
mRawResultQueue.put((int) request.getTag(), rawBuilder);
+ mYuvResultQueue.put((int) request.getTag(), yuvBuilder);
mCaptureSession.capture(request, mCaptureCallback, mBackgroundHandler);
}
diff --git a/app/src/main/java/com/xypower/mppreview/ImageSaver.java b/app/src/main/java/com/xypower/mppreview/ImageSaver.java
index 3b71516..74c4075 100644
--- a/app/src/main/java/com/xypower/mppreview/ImageSaver.java
+++ b/app/src/main/java/com/xypower/mppreview/ImageSaver.java
@@ -16,6 +16,7 @@ import androidx.annotation.NonNull;
import com.xypower.mppreview.bean.PngPhotoBean;
import com.xypower.mppreview.interfaces.CompleteCallback;
+import com.xypower.mppreview.utils.DeepCopyUtil;
import com.xypower.mppreview.utils.ImageConverterUtil;
import java.io.File;
@@ -29,7 +30,7 @@ import java.util.List;
public class ImageSaver implements Runnable {
private final static String TAG = "HDR";
- private final Image mImage;
+ private Image mImage;
private final File mFile;
private final CaptureResult mCaptureResult;
private final CameraCharacteristics mCharacteristics;
@@ -38,6 +39,7 @@ public class ImageSaver implements Runnable {
private final ImagePair mImagePair;
private final Camera2RawFragment.RefCountedAutoCloseable mReader;
+ private ArrayList objects = new ArrayList<>();
public static class ImageInfo {
public long exposureTime;
@@ -53,11 +55,14 @@ public class ImageSaver implements Runnable {
public static class ImagePair {
public List mImages;
+
+ public List images;
public int mExpectedCount;
public Runnable mRunnable;
public ImagePair(int expectedCount) {
mImages = new ArrayList<>();
+ images = new ArrayList<>();
mExpectedCount = expectedCount;
mRunnable = null;
}
@@ -79,9 +84,24 @@ public class ImageSaver implements Runnable {
}
}
+ public void addMImage(Image image) {
+ boolean isFull = false;
+ synchronized (mImages) {
+ images.add(image);
+ isFull = (images.size() == mExpectedCount);
+ }
+
+ if (mRunnable != null && isFull) {
+ mRunnable.run();
+ }
+ }
+
public List getImages() {
return mImages;
}
+ public List getMImages() {
+ return images;
+ }
}
public static abstract class ImagePairRunnable implements Runnable {
@@ -133,12 +153,18 @@ public class ImageSaver implements Runnable {
break;
}
case ImageFormat.YUV_420_888: {
+// if (mImagePair != null) {
+// mImagePair.addMImage(mImage);
+// }
+
new Thread(new Runnable() {
@Override
public void run() {
Log.d("测试", "ceshi");
+ // Image image = DeepCopyUtil.deepCopy(mImage);
RenderScript rs = RenderScript.create(mContext);
new ImageConverterUtil().saveYuvImageFromImageReader(mImage, rs, "");
+
}
}).start();
break;
diff --git a/app/src/main/java/com/xypower/mppreview/MainActivity.java b/app/src/main/java/com/xypower/mppreview/MainActivity.java
index 4c6fa6a..b96864c 100644
--- a/app/src/main/java/com/xypower/mppreview/MainActivity.java
+++ b/app/src/main/java/com/xypower/mppreview/MainActivity.java
@@ -14,6 +14,7 @@ import android.Manifest;
import android.content.Context;
import android.content.Intent;
import android.content.pm.PackageManager;
+import android.graphics.Bitmap;
import android.hardware.camera2.CameraAccessException;
import android.hardware.camera2.CameraManager;
import android.net.ConnectivityManager;
@@ -63,6 +64,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private com.xypower.mppreview.databinding.ActivityMainBinding viewBinding;
private int numberOfCameras;
+ public static native boolean test();
+
+
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
@@ -184,7 +188,9 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
startActivity(intent);
break;
case R.id.systakepic:
- PhotoUtil.openCamera(this, photoResultLauncher);
+// PhotoUtil.openCamera(this, photoResultLauncher);
+// test();
+
break;
// case R.id.channel1:
// openChannelActivity(0);
diff --git a/app/src/main/java/com/xypower/mppreview/utils/DeepCopyUtil.java b/app/src/main/java/com/xypower/mppreview/utils/DeepCopyUtil.java
new file mode 100644
index 0000000..d944be6
--- /dev/null
+++ b/app/src/main/java/com/xypower/mppreview/utils/DeepCopyUtil.java
@@ -0,0 +1,22 @@
+package com.xypower.mppreview.utils;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+
+public class DeepCopyUtil {
+ public static T deepCopy(T object) throws IOException, ClassNotFoundException {
+ // 将对象写入字节流
+ ByteArrayOutputStream bos = new ByteArrayOutputStream();
+ ObjectOutputStream oos = new ObjectOutputStream(bos);
+ oos.writeObject(object);
+ oos.flush();
+
+ // 从字节流中读取对象
+ ByteArrayInputStream bis = new ByteArrayInputStream(bos.toByteArray());
+ ObjectInputStream ois = new ObjectInputStream(bis);
+ return (T) ois.readObject();
+ }
+}
diff --git a/app/src/main/java/com/xypower/mppreview/utils/ImageConverterUtil.java b/app/src/main/java/com/xypower/mppreview/utils/ImageConverterUtil.java
index 213ce22..49cf464 100644
--- a/app/src/main/java/com/xypower/mppreview/utils/ImageConverterUtil.java
+++ b/app/src/main/java/com/xypower/mppreview/utils/ImageConverterUtil.java
@@ -48,7 +48,7 @@ public class ImageConverterUtil {
}
}
- private Bitmap imageYuvToBitmap(Image image, RenderScript rs) {
+ public Bitmap imageYuvToBitmap(Image image, RenderScript rs) {
if (image.getFormat() != ImageFormat.YUV_420_888) {
throw new IllegalArgumentException("Only YUV_420_888 format is supported");
}