You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
MpPreview/app/src/main/java/com/xypower/mppreview/ui/CameraChannelActivity.java

168 lines
6.4 KiB
Java

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

package com.xypower.mppreview.ui;
import static java.lang.System.loadLibrary;
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.util.Log;
import android.view.View;
import android.widget.Toast;
import com.google.common.util.concurrent.ListenableFuture;
import com.xypower.mppreview.MyAnalyzer;
import com.xypower.mppreview.R;
import com.xypower.mppreview.bean.Contants;
import com.xypower.mppreview.databinding.ActivityCameraChannelBinding;
import java.io.File;
import java.text.SimpleDateFormat;
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 {
static {
loadLibrary("mppreview");
}
private com.xypower.mppreview.databinding.ActivityCameraChannelBinding viewBinding;
private int camerid;
private ImageCapture imageCapture;
private ExecutorService cameraExecutor;
private File outputDirectory;
private static native void setInt(int cmd, int val);
@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);
viewBinding.foward.setOnClickListener(this);
viewBinding.back.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.image_capture_button:
takePhoto();
break;
case R.id.foward:
setInt(311, 101);
break;
case R.id.back:
setInt(311, 201);
break;
}
}
private void startCamera(int cameraid) {
// 将Camera的生命周期和Activity绑定在一起设定生命周期所有者这样就不用手动控制相机的启动和关闭。
ListenableFuture<ProcessCameraProvider> 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<CameraInfo> 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;
}
}