diff --git a/app/build.gradle b/app/build.gradle
index cca0dce..8a43f5d 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -54,6 +54,9 @@ android {
}
}
+ buildFeatures {
+ viewBinding true
+ }
}
dependencies {
@@ -63,4 +66,20 @@ dependencies {
testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
+
+ //CameraX
+// implementation "androidx.camera:camera-core:1.4.1"
+// implementation "androidx.camera:camera-camera2:1.4.1"
+// implementation "androidx.camera:camera-view:1.4.1"
+// implementation "androidx.camera:camera-lifecycle:1.4.1"
+// implementation "androidx.camera:camera-video:1.4.1"
+
+// CameraX core library using camera2 implementation
+ implementation "androidx.camera:camera-camera2:1.1.0"
+// CameraX Lifecycle Library
+ implementation "androidx.camera:camera-lifecycle:1.1.0"
+// CameraX View class
+ implementation "androidx.camera:camera-view:1.1.0"
+
+
}
\ No newline at end of file
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 9372d41..b88ee58 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -21,10 +21,12 @@
android:theme="@style/Theme.MpPreview"
android:requestLegacyExternalStorage="true"
tools:targetApi="30">
+
+ android:exported="false" />
diff --git a/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java b/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java
index ccbb94c..06e912b 100644
--- a/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java
+++ b/app/src/main/java/com/xypower/mppreview/Camera2RawFragment.java
@@ -1101,7 +1101,8 @@ public class Camera2RawFragment extends Fragment {
Range range = mCharacteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_RANGE);
Rational rational = mCharacteristics.get(CameraCharacteristics.CONTROL_AE_COMPENSATION_STEP);
double step = rational.doubleValue();
-
+ captureBuilder.set(CaptureRequest.EDGE_MODE, CaptureRequest.EDGE_MODE_HIGH_QUALITY);
+ captureBuilder.set(CaptureRequest.NOISE_REDUCTION_MODE, CaptureRequest.NOISE_REDUCTION_MODE_HIGH_QUALITY);
if (pic1 < 21) {
// mCharacteristics.get(CameraMetadata.CONTROL_AE_COMPENSATION_STEP)
ArrayList mlist = new ArrayList<>();
diff --git a/app/src/main/java/com/xypower/mppreview/CameraChannelActivity.java b/app/src/main/java/com/xypower/mppreview/CameraChannelActivity.java
new file mode 100644
index 0000000..bad403d
--- /dev/null
+++ b/app/src/main/java/com/xypower/mppreview/CameraChannelActivity.java
@@ -0,0 +1,151 @@
+package com.xypower.mppreview;
+
+import static android.os.Environment.getExternalStoragePublicDirectory;
+
+import androidx.annotation.NonNull;
+import androidx.appcompat.app.AppCompatActivity;
+import androidx.camera.core.CameraInfo;
+import androidx.camera.core.CameraSelector;
+import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.ImageCapture;
+import androidx.camera.core.ImageCaptureException;
+import androidx.camera.core.Preview;
+import androidx.camera.lifecycle.ProcessCameraProvider;
+import androidx.camera.view.PreviewView;
+import androidx.core.content.ContextCompat;
+
+import android.net.Uri;
+import android.os.Bundle;
+import android.os.Environment;
+import android.util.Log;
+import android.view.View;
+import android.widget.Toast;
+
+import com.google.common.util.concurrent.ListenableFuture;
+import com.xypower.mppreview.bean.Contants;
+import com.xypower.mppreview.databinding.ActivityCameraChannelBinding;
+
+import java.io.File;
+import java.io.IOException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.List;
+import java.util.Locale;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+
+public class CameraChannelActivity extends AppCompatActivity implements View.OnClickListener {
+
+ private com.xypower.mppreview.databinding.ActivityCameraChannelBinding viewBinding;
+ private int camerid;
+ private ImageCapture imageCapture;
+ private ExecutorService cameraExecutor;
+ private File outputDirectory;
+
+ @Override
+ protected void onCreate(Bundle savedInstanceState) {
+ super.onCreate(savedInstanceState);
+ viewBinding = ActivityCameraChannelBinding.inflate(getLayoutInflater());
+ setContentView(viewBinding.getRoot());
+ camerid = getIntent().getIntExtra(Contants.CAMERAID, 0);
+ initEvent();
+
+ // 设置照片等保存的位置
+ outputDirectory = getOutputDirectory();
+
+ cameraExecutor = Executors.newSingleThreadExecutor();
+
+ startCamera(camerid);
+ }
+
+ @Override
+ protected void onDestroy() {
+ super.onDestroy();
+ cameraExecutor.shutdown();
+ }
+
+ private void initEvent() {
+ viewBinding.imageCaptureButton.setOnClickListener(this);
+ }
+
+ @Override
+ public void onClick(View v) {
+ takePhoto();
+ }
+
+ private void startCamera(int cameraid) {
+ // 将Camera的生命周期和Activity绑定在一起(设定生命周期所有者),这样就不用手动控制相机的启动和关闭。
+ ListenableFuture cameraProviderFuture = ProcessCameraProvider.getInstance(this);
+
+ cameraProviderFuture.addListener(() -> {
+ try {
+ // 将你的相机和当前生命周期的所有者绑定所需的对象
+ ProcessCameraProvider processCameraProvider = cameraProviderFuture.get();
+
+ // 创建一个Preview 实例,并设置该实例的 surface 提供者(provider)。
+ PreviewView viewFinder = viewBinding.viewFinder;
+ Preview preview = new Preview.Builder().build();
+ preview.setSurfaceProvider(viewFinder.getSurfaceProvider());
+
+ // 选择后置摄像头作为默认摄像头
+// CameraSelector cameraSelector = CameraSelector.DEFAULT_BACK_CAMERA;
+
+ List availableCameraInfos = processCameraProvider.getAvailableCameraInfos();
+ CameraInfo cameraInfo = availableCameraInfos.get(cameraid);
+ CameraSelector cameraSelector = cameraInfo.getCameraSelector();
+
+ // 创建拍照所需的实例
+ imageCapture = new ImageCapture.Builder().build();
+
+ // 设置预览帧分析
+ ImageAnalysis imageAnalysis = new ImageAnalysis.Builder().build();
+ imageAnalysis.setAnalyzer(cameraExecutor, new MyAnalyzer());
+
+ // 重新绑定用例前先解绑
+ processCameraProvider.unbindAll();
+
+ // 绑定用例至相机
+ processCameraProvider.bindToLifecycle(CameraChannelActivity.this, cameraSelector, preview,imageCapture,imageAnalysis);
+
+ } catch (Exception e) {
+ Log.e(Contants.TAG, "用例绑定失败!" + e);
+ }
+ }, ContextCompat.getMainExecutor(this));
+
+ }
+
+ private void takePhoto() {
+ // 确保imageCapture 已经被实例化, 否则程序将可能崩溃
+ if (imageCapture != null) {
+ // 创建带时间戳的输出文件以保存图片,带时间戳是为了保证文件名唯一
+ File photoFile = new File(outputDirectory, new SimpleDateFormat(Contants.FILENAME_FORMAT, Locale.SIMPLIFIED_CHINESE).format(System.currentTimeMillis()) + ".jpg");
+
+ // 创建 output option 对象,用以指定照片的输出方式
+ ImageCapture.OutputFileOptions outputFileOptions = new ImageCapture.OutputFileOptions.Builder(photoFile).build();
+
+ // 执行takePicture(拍照)方法
+ imageCapture.takePicture(outputFileOptions, ContextCompat.getMainExecutor(this), new ImageCapture.OnImageSavedCallback() {// 保存照片时的回调
+ @Override
+ public void onImageSaved(@NonNull ImageCapture.OutputFileResults outputFileResults) {
+ Uri savedUri = Uri.fromFile(photoFile);
+ String msg = "照片捕获成功! " + savedUri;
+ Toast.makeText(getBaseContext(), msg, Toast.LENGTH_SHORT).show();
+ Log.d(Contants.TAG, msg);
+ }
+
+ @Override
+ public void onError(@NonNull ImageCaptureException exception) {
+ Log.e(Contants.TAG, "Photo capture failed: " + exception.getMessage());
+ }
+ });
+ }
+ }
+
+ private File getOutputDirectory() {
+ File mediaDir = new File(getExternalMediaDirs()[0], getString(R.string.app_name));
+ boolean isExist = mediaDir.exists() || mediaDir.mkdir();
+ return isExist ? mediaDir : null;
+ }
+
+
+}
\ No newline at end of file
diff --git a/app/src/main/java/com/xypower/mppreview/MainActivity.java b/app/src/main/java/com/xypower/mppreview/MainActivity.java
index 25bf06c..b957289 100644
--- a/app/src/main/java/com/xypower/mppreview/MainActivity.java
+++ b/app/src/main/java/com/xypower/mppreview/MainActivity.java
@@ -13,14 +13,12 @@ import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.os.Bundle;
-import android.text.Editable;
import android.view.View;
import android.widget.AdapterView;
import android.widget.Button;
-import android.widget.EditText;
-import android.widget.Spinner;
import com.xypower.mppreview.bean.Contants;
+import com.xypower.mppreview.databinding.ActivityMainBinding;
import java.io.File;
@@ -37,6 +35,7 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
private Button hdrtakepic;
private ActivityResultLauncher photoResultLauncher;
private int picsize = 0;
+ private com.xypower.mppreview.databinding.ActivityMainBinding viewBinding;
protected native void test();
@@ -44,7 +43,8 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
- setContentView(R.layout.activity_main);
+ viewBinding = ActivityMainBinding.inflate(getLayoutInflater());
+ setContentView(viewBinding.getRoot());
initView();
initActivityResult();
@@ -82,12 +82,15 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
}
private void initView() {
- hdrtakepic = findViewById(R.id.hdrtakepic);
- systakepic = findViewById(R.id.systakepic);
- Spinner spinner = findViewById(R.id.spinner);
- hdrtakepic.setOnClickListener(this);
- systakepic.setOnClickListener(this);
- spinner.setOnItemSelectedListener(this);
+ viewBinding.hdrtakepic.setOnClickListener(this);
+ viewBinding.systakepic.setOnClickListener(this);
+ viewBinding.spinner.setOnItemSelectedListener(this);
+ viewBinding.channel1.setOnClickListener(this);
+ viewBinding.channel2.setOnClickListener(this);
+ viewBinding.channel3.setOnClickListener(this);
+ viewBinding.channel4.setOnClickListener(this);
+ viewBinding.channel5.setOnClickListener(this);
+ viewBinding.channel6.setOnClickListener(this);
}
private void initActivityResult() {
@@ -135,10 +138,34 @@ public class MainActivity extends AppCompatActivity implements View.OnClickListe
case R.id.systakepic:
PhotoUtil.openCamera(this, photoResultLauncher);
break;
+ case R.id.channel1:
+ openChannelActivity(0);
+ break;
+ case R.id.channel2:
+ openChannelActivity(1);
+ break;
+ case R.id.channel3:
+ openChannelActivity(2);
+ break;
+ case R.id.channel4:
+ openChannelActivity(3);
+ break;
+ case R.id.channel5:
+ openChannelActivity(4);
+ break;
+ case R.id.channel6:
+ openChannelActivity(5);
+ break;
}
}
+ public void openChannelActivity(int channel) {
+ Intent intent = new Intent(this, CameraChannelActivity.class);
+ intent.putExtra(Contants.CAMERAID, channel);
+ startActivity(intent);
+ }
+
@Override
public void onItemSelected(AdapterView> parent, View view, int position, long id) {
diff --git a/app/src/main/java/com/xypower/mppreview/MyAnalyzer.java b/app/src/main/java/com/xypower/mppreview/MyAnalyzer.java
new file mode 100644
index 0000000..8e67668
--- /dev/null
+++ b/app/src/main/java/com/xypower/mppreview/MyAnalyzer.java
@@ -0,0 +1,21 @@
+package com.xypower.mppreview;
+
+import android.annotation.SuppressLint;
+import android.util.Log;
+
+import androidx.annotation.NonNull;
+import androidx.camera.core.ImageAnalysis;
+import androidx.camera.core.ImageProxy;
+
+import com.xypower.mppreview.bean.Contants;
+
+import java.util.Objects;
+
+public class MyAnalyzer implements ImageAnalysis.Analyzer{
+ @SuppressLint("UnsafeOptInUsageError")
+ @Override
+ public void analyze(@NonNull ImageProxy image) {
+ Log.d(Contants.TAG, "Image's stamp is " + Objects.requireNonNull(image.getImage()).getTimestamp());
+ image.close();
+ }
+}
diff --git a/app/src/main/java/com/xypower/mppreview/bean/Contants.java b/app/src/main/java/com/xypower/mppreview/bean/Contants.java
index d24dc01..1cbeb10 100644
--- a/app/src/main/java/com/xypower/mppreview/bean/Contants.java
+++ b/app/src/main/java/com/xypower/mppreview/bean/Contants.java
@@ -1,5 +1,10 @@
package com.xypower.mppreview.bean;
+import java.io.File;
+
public class Contants {
+ public static final String TAG = "MpPriview";
public static final String HDRNUM = "hdrnum";
+ public static final String CAMERAID = "CAMERAID";
+ public static final String FILENAME_FORMAT = "yyyy-MM-dd-HH-mm-ss-SSS";
}
diff --git a/app/src/main/res/layout/activity_camera_channel.xml b/app/src/main/res/layout/activity_camera_channel.xml
new file mode 100644
index 0000000..31f5856
--- /dev/null
+++ b/app/src/main/res/layout/activity_camera_channel.xml
@@ -0,0 +1,44 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_main.xml b/app/src/main/res/layout/activity_main.xml
index 1a1cbae..87a15c7 100644
--- a/app/src/main/res/layout/activity_main.xml
+++ b/app/src/main/res/layout/activity_main.xml
@@ -29,7 +29,7 @@
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file