北京网站建设公司排行,不用付费的正能量软件,永州静默管理,企业宣传片制作拍摄前面两篇介绍了Camera1和Camera2的使用#xff0c;发现Camera API从1到2的变化非常大#xff0c;Camera2的复杂度提升了不少#xff0c;官方为了让我们更容易使用Camera#xff0c;出了个一个官方的库cameraview。不过这个库已经Deprecated#xff0c;官方建议使用Jetpack…前面两篇介绍了Camera1和Camera2的使用发现Camera API从1到2的变化非常大Camera2的复杂度提升了不少官方为了让我们更容易使用Camera出了个一个官方的库cameraview。不过这个库已经Deprecated官方建议使用Jetpack CameraX 替代。本篇文章就介绍下CameraView和CameraX的使用CameraViewCameraView的目的就是帮助开发者能够快速集成Camera1和Camera2的特性可以用下面这张表来说明API LevelCamera APIPreview View9-13Camera1SurfaceView14-20Camera1TextureView21-23Camera2TextureView24Camera2SurfaceView开发流程CameraView定义xml中定义android:idid/cameraandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:keepScreenOntrueandroid:adjustViewBoundstrueapp:autoFocustrueapp:aspectRatio4:3app:facingbackapp:flashauto/xml中可以配置autoFocus是否自动对焦aspectRatio预览画面比例facing前后摄像头flash闪光灯模式增加生命周期Overrideprotected void onResume() {super.onResume();mCameraView.start();}Overrideprotected void onPause() {mCameraView.stop();super.onPause();}这样声明后就可以完成预览的工作了相机状态回调在xml声明CameraView后增加回调if (mCameraView ! null) {mCameraView.addCallback(mCallback);}...private CameraView.Callback mCallback new CameraView.Callback() {Overridepublic void onCameraOpened(CameraView cameraView) {Log.d(TAG, onCameraOpened);}Overridepublic void onCameraClosed(CameraView cameraView) {Log.d(TAG, onCameraClosed);}Overridepublic void onPictureTaken(CameraView cameraView, final byte[] data) {Log.d(TAG, onPictureTaken data.length);Toast.makeText(cameraView.getContext(), R.string.picture_taken, Toast.LENGTH_SHORT).show();getBackgroundHandler().post(new Runnable() {Overridepublic void run() {File file new File(getExternalFilesDir(Environment.DIRECTORY_PICTURES),picture.jpg);Log.d(TAG, onPictureTaken file path: file.getPath());OutputStream os null;try {os new FileOutputStream(file);os.write(data);os.close();} catch (IOException e) {Log.w(TAG, Cannot write to file, e);} finally {if (os ! null) {try {os.close();} catch (IOException e) {// Ignore}}}}});}};有三个回调方法相机打开相机关闭和拍照。拍照mCameraView.takePicture();就是这么简单点击后拍照然后回调中处理图像数据CameraXCameraX 是一个 Jetpack 支持库目的是简化Camera的开发工作它是基于Camera2 API的基础向后兼容至 Android 5.0(API 级别 21)。它有以下几个特性易用性只需要几行代码就可以实现预览和拍照保持设备的一致性在不同相机设备上对宽高比、屏幕方向、旋转、预览大小和高分辨率图片大小做到都可以正常使用相机特性的扩展增加人像、HDR、夜间模式和美颜等功能开发流程库引用目前CameraX最新版本是1.0.0-alpha06在app的build.gradle引用dependencies {// CameraX core library.def camerax_version 1.0.0-alpha06implementation androidx.camera:camera-core:${camerax_version}// If you want to use Camera2 extensions.implementation androidx.camera:camera-camera2:${camerax_version}def camerax_view_version 1.0.0-alpha03def camerax_ext_version 1.0.0-alpha03//other// If you to use the Camera View classimplementation androidx.camera:camera-view:$camerax_view_version// If you to use Camera Extensionsimplementation androidx.camera:camera-extensions:$camerax_ext_version}因为CameraX是一个 Jetpack 支持库相机的打开和释放都是使用了Jetpack的Lifecycle来进行处理。预览预览参数设置使用PreviewConfig.Builder()实现PreviewConfig config new PreviewConfig.Builder().setLensFacing(CameraX.LensFacing.BACK).setTargetRotation(mTextureView.getDisplay().getRotation()).setTargetResolution(new Size(640, 480)).build();Preview preview new Preview(config);preview.setOnPreviewOutputUpdateListener(new Preview.OnPreviewOutputUpdateListener() {Overridepublic void onUpdated(NonNull Preview.PreviewOutput output) {if (mTextureView.getParent() instanceof ViewGroup) {ViewGroup viewGroup (ViewGroup) mTextureView.getParent();viewGroup.removeView(mTextureView);viewGroup.addView(mTextureView, 0);mTextureView.setSurfaceTexture(output.getSurfaceTexture());updateTransform();}}});//lifecycleCameraX.bindToLifecycle(this, preview);PreivewConfig.Builder可以设置的属性很多这里只设置了摄像头、旋转方向、预览分辨率还有很多其他方法大家可以自行试验。在preview回调监听中把output的SurfaceTexture设置到mTextureView中实现图像预览最后增加Lifecycle的绑定。拍照ImageCaptureConfig captureConfig new ImageCaptureConfig.Builder().setTargetAspectRatio(AspectRatio.RATIO_16_9).setCaptureMode(ImageCapture.CaptureMode.MIN_LATENCY).setTargetRotation(getWindowManager().getDefaultDisplay().getRotation()).build();ImageCapture imageCapture new ImageCapture(captureConfig);mTakePicture.setOnClickListener((view) - {final File file new File(getExternalMediaDirs()[0], System.currentTimeMillis() .jpg);Log.d(DEBUG, ##### file path: file.getPath());imageCapture.takePicture(file, ContextCompat.getMainExecutor(getApplicationContext()), new ImageCapture.OnImageSavedListener() {Overridepublic void onImageSaved(NonNull File file) {Log.d(DEBUG, ##### onImageSaved: file.getPath());}Overridepublic void onError(NonNull ImageCapture.ImageCaptureError imageCaptureError, NonNull String message, Nullable Throwable cause) {Log.d(DEBUG, ##### onError: message);}});});CameraX.bindToLifecycle(this, preview, imageCapture);拍照的参数通过ImageCaptureConfig.Builder设置这里只设置了图片宽高比、拍摄模式和旋转方向还有很多其他方法大家可以自行试验。真正调用拍照的方法takePicture(OnImageCapturedListener)此方法为拍摄的图片提供内存缓冲区。takePicture(File, OnImageSavedListener)此方法将拍摄的图片保存到提供的文件位置。takePicture(File, OnImageSavedListener, Metadata)此方法可用于指定要嵌入已保存文件的 Exif 中的元数据。例子调用的是takePicture(File, OnImageSavedListener)直接存为文件。最后再增加Lifecycle的绑定。图片分析ImageAnalysisConfig analysisConfig new ImageAnalysisConfig.Builder().setImageReaderMode(ImageAnalysis.ImageReaderMode.ACQUIRE_LATEST_IMAGE).build();ImageAnalysis imageAnalysis new ImageAnalysis(analysisConfig);imageAnalysis.setAnalyzer(ContextCompat.getMainExecutor(getApplicationContext()),new LuminosityAnalyzer());CameraX.bindToLifecycle(this, preview, imageCapture, imageAnalysis);...private class LuminosityAnalyzer implements ImageAnalysis.Analyzer {private long lastAnalyzedTimestamp 0L;Overridepublic void analyze(ImageProxy image, int rotationDegrees) {final Image img image.getImage();if (img ! null) {Log.d(DEBUG, img.getWidth() , img.getHeight());}}}图片分析不是必要的步骤但是ImageAnalysis可以对每帧图像进行分析。设置参数通过ImageAnalysisConfig.Builder()这里只设置了ImageReaderMode它有两种模式阻止模式(ImageReaderMode.ACQUIRE_NEXT_IMAGE)就是Camera2中的acquireNextImage()获取下一个最新的可用Image非阻止模式(ImageReaderMode.ACQUIRE_LATEST_IMAGE)Camera2中的acquireLatestImage()获得图像队列中最新的图片并且会清空队列,删除已有的旧的图像最后还是增加Lifecycle的绑定。CameraX的使用也非常简单把Camera2中复杂的API封装到统一的config中只需要几行代码就实现需要的功能。文章中涉及到的代码参考