public class CaptureActivity extends BaseActivity {
//设置使用后置摄像头
private CameraX.LensFacing mLensFacing = CameraX.LensFacing.BACK;
//设置旋转角度
private int rotation_0=Surface.ROTATION_0;
//设置分辨率
private Size resolution = new Size(1280, 720);
//设置宽高比
private Rational rational = new Rational(9, 16);
//预览
private Preview preview;
//拍照
private ImageCapture imageCapture;
//视频录制
private VideoCapture videoCapture;
private ActivityLayoutCaptureBinding binding;
//记录是拍照还是录制视频
private boolean takingPicture;
//照片或视频存放路径
private String path;
public static final int REQ_CAPTURE = 10001;
public static final String RESULT_FILE_PATH = "file_path";
public static final String RESULT_FILE_WIDTH = "file_width";
public static final String RESULT_FILE_HEIGHT = "file_height";
public static final String RESULT_FILE_TYPE = "file_type";
public static void startActivityForResult(Activity activity) {
Intent intent = new Intent(activity, CaptureActivity.class);
activity.startActivityForResult(intent, REQ_CAPTURE);
}
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
binding = DataBindingUtil.setContentView(this, R.layout.activity_layout_capture);
// 申请权限验证================省略==============================================================
//初始化
bindCameraX();
//点击拍摄按钮
binding.recordview.setOnRecordListener(new RecordView.onRecordListener() {
@Override
public void onClick() {
takingPicture=true;
File file=new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
System.currentTimeMillis() + ".jpeg");
//相机拍照 参数1 文件存储地址 参数2 拍照完成后的回调
imageCapture.takePicture(file, new ImageCapture.OnImageSavedListener() {
//此接口在子线程内
@Override
public void onImageSaved(@NonNull File file) {
onFileSave(file);
}
@Override //此接口在子线程内
public void onError(@NonNull ImageCapture.UseCaseError useCaseError, @NonNull String message, @Nullable Throwable cause) {
Log.i("message","拍照失败"+message);
}
});
}
@SuppressLint("RestrictedApi")
@Override
public void onLongClick() {
takingPicture = false;
File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS),
System.currentTimeMillis() + ".mp4");
// 录制视频 参数1文件保存地址 参数2回调接口
videoCapture.startRecording(file, new VideoCapture.OnVideoSavedListener() {
@Override //此接口在子线程内
public void onVideoSaved(File file) {
onFileSave(file);
}
@Override //此接口在子线程内
public void onError(VideoCapture.UseCaseError useCaseError, String message, @Nullable Throwable cause) {
Log.i("message","录制失败"+message);
}
});
}
@SuppressLint("RestrictedApi")
@Override
public void onFinish() {
//结束录制
videoCapture.stopRecording();
}
});
}
@SuppressLint("RestrictedApi")
private void bindCameraX()
{
CameraX.unbindAll();
//查询一下当前要使用的设备摄像头(比如后置摄像头)是否存在
boolean hasAvailableCameraId = false;
try {
hasAvailableCameraId = CameraX.hasCameraWithLensFacing(mLensFacing);
} catch (CameraInfoUnavailableException e) {
e.printStackTrace();
}
if (!hasAvailableCameraId) {
Toast.makeText(this,"无可用的设备cameraId!,请检查设备的相机是否被占用",Toast.LENGTH_SHORT);
finish();
return;
}
//查询一下是否存在可用的cameraId.形式如:后置:"0",前置:"1"
String cameraIdForLensFacing = null;
try {
cameraIdForLensFacing = CameraX.getCameraFactory().cameraIdForLensFacing(mLensFacing);
} catch (CameraInfoUnavailableException e) {
e.printStackTrace();
}
if (TextUtils.isEmpty(cameraIdForLensFacing)) {
Toast.makeText(this,"无可用的设备cameraId!,请检查设备的相机是否被占用",Toast.LENGTH_SHORT);
finish();
return;
}
PreviewConfig config= new PreviewConfig.Builder()
//设置使用前置还是后置摄像头
.setLensFacing(mLensFacing)
//设置旋转角度
.setTargetRotation(rotation_0)
//设置预览时分辨率
.setTargetResolution(resolution)
//设置屏幕宽高比 9:16
.setTargetAspectRatio(rational).build();
preview = new Preview(config);
imageCapture = new ImageCapture(new ImageCaptureConfig.Builder()
.setTargetResolution(resolution)
.setTargetAspectRatio(rational)
.setLensFacing(mLensFacing)
.setTargetRotation(rotation_0).build());
videoCapture = new VideoCapture(new VideoCaptureConfig.Builder()
.setTargetRotation(rotation_0)
.setTargetAspectRatio(rational)
.setLensFacing(mLensFacing)
.setTargetResolution(resolution)
//设置比特率
.setBitRate(3*1024*1024)
//设置帧率
.setVideoFrameRate(25).build());
//视频流的每一帧会回调到这个方法
preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {
@Override
public void onUpdated(Preview.PreviewOutput output) {
//要先从父布局移除然后再添加进来才能正确渲染
TextureView textureView = binding.textureView;
ViewGroup viewGroup=(ViewGroup)textureView.getParent();
viewGroup.removeView(textureView);
viewGroup.addView(textureView,0);
textureView.setSurfaceTexture(output.getSurfaceTexture());
}
});
//上面配置的都是我们期望的分辨率
List<UseCase> newUseCase=new ArrayList<>();
newUseCase.add(preview);
newUseCase.add(imageCapture);
newUseCase.add(videoCapture);
//下面我们要查询一下 当前设备它所支持的分辨率有哪些,然后再更新一下 所配置的几个usecase
Map<UseCase, Size> resolutions = CameraX.getSurfaceManager().
getSuggestedResolutions(cameraIdForLensFacing, null, newUseCase);
Iterator<Map.Entry<UseCase, Size>> iterator = resolutions.entrySet().iterator();
while (iterator.hasNext()) {
Map.Entry<UseCase, Size> next = iterator.next();
UseCase useCase = next.getKey();
Size value = next.getValue();
Map<String, Size> update = new HashMap<>();
update.put(cameraIdForLensFacing, value);
useCase.updateSuggestedResolution(update);
}
CameraX.bindToLifecycle(this,preview,imageCapture,videoCapture);
}
@Override
protected void onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
super.onActivityResult(requestCode, resultCode, data);
Log.i("requsetnnn",requestCode+","+resultCode);
if (requestCode==PreviewActivity.REQ_PREVIEW&&resultCode==RESULT_OK)
{
Intent intent=new Intent();
intent.putExtra(RESULT_FILE_PATH,path);
//当设备处于竖屏情况时,宽高的值 需要互换,横屏不需要
intent.putExtra(RESULT_FILE_WIDTH, resolution.getHeight());
intent.putExtra(RESULT_FILE_HEIGHT, resolution.getWidth());
intent.putExtra(RESULT_FILE_TYPE, !takingPicture);
setResult(RESULT_OK, intent);
finish();
}
}
private void onFileSave(File file) {
path = file.getAbsolutePath();
String taketype=takingPicture?"image/jpeg":"video/mp4";
//扫描文件
MediaScannerConnection.scanFile(this,new String[]{path},new String[]{taketype},null);
binding.recordview.PostInvalidate();
PreviewActivity.startActivityForResult(this,path,!takingPicture,"完成");
}
@Override
protected void onDestroy() {
CameraX.unbindAll();
binding.recordview.PostInvalidate();
super.onDestroy();
}
}
笔记 camearX基本使用
最新推荐文章于 2024-08-24 03:42:57 发布