如何打开后置摄像头的预览界面 摄像头视频预览

在上一篇文章中 , 我们实现了获取相机的权限ohos.permission.CAMERA之后 , 让手机屏幕打开拍摄外部环境的画面 , 预览的画面也必须是后置摄像头拍摄的画面 。
   

如何打开后置摄像头的预览界面 摄像头视频预览

文章插图
   如果你觉得打开拍摄图片的功能很复杂 , 我建议你参考一下HarmonyOS Developer根据开发->媒体->相机相机开发指导在界面内容中梳理其功能 。
   
如何打开后置摄像头的预览界面 摄像头视频预览

文章插图
   根据上图相机开发过程 , 华为手机的后置摄像头为了打开拍摄预览图片 , 我们必须创建相机设备的对象 。为了更直观、更简单地方便您实现此功能 , 我仍然根据我自己的项目结构呈现相关的代码内容 。
   一.在项目中新建一个CameraView类继承DirectionalLayout , 单独代表相机的视图对象 , 创建相机设备 。   工程结构图如下:
   
如何打开后置摄像头的预览界面 摄像头视频预览

文章插图
   代码内容如下:
   import ohos.agp.components.ComponentContainer; import ohos.agp.components.DirectionalLayout; import ohos.agp.components.surfaceprovider.SurfaceProvider; import ohos.agp.graphics.Surface; import ohos.agp.graphics.SurfaceOps; import ohos.agp.window.service.WindowManager; import ohos.app.Context; import ohos.eventhandler.EventHandler; import ohos.eventhandler.EventRunner; import ohos.hiviewdfx.HiLog; import ohos.hiviewdfx.HiLogLabel; import ohos.media.camera.CameraKit; import ohos.media.camera.device.Camera; import ohos.media.camera.device.CameraConfig; import ohos.media.camera.device.CameraStateCallback; import ohos.media.camera.device.FrameConfig; import static ohos.media.camera.device.Camera.FrameConfigType.FRAME_CONFIG_PREVIEW; public class CameraView extends DirectionalLayout{ static final HiLogLabel label = new HiLogLabel(HiLog.LOG_APP,0x00311,"MY_TAG"); //相机设备 private Camera cameraSurface; //相机预览模板的配置对象 private SurfaceProvider surfaceProvider; //相机预览模板 private Surface previewSurface; /上下文 private Context context; //摄像头类型:前摄像头 , 后摄像头 private String cameraId private EventHandler eventHandler = new EventHandler(EventRunner.current() { };private ComponentContainer componentContainer; /public CameraView(Context context) { super(context); this.context = context; initSurface(context); } //第一步:初始化照相机预览图片SurfaceProvider private void initSurface(Context context){ WindowManager.getInstance().getTopWindow().get().setTransparent(true); DirectionalLayout.LayoutConfig params = new DirectionalLayout.LayoutConfig( ComponentContainer.LayoutConfig.MATCH_PARENT,ComponentContainer.LayoutConfig.MATCH_PARENT ); surfaceProvider = new SurfaceProvider(context); surfaceProvider.setLayoutConfig(params); surfaceProvider.pinToZTop(false); surfaceProvider.getSurfaceOps().get().addCallback(new SurfaceCallBack()); addComponent(surfaceProvider); } //第二步:创建Surface的监听器SurfaceCallBack , 正常感知SurfaceProvider 的创改变或销毁 private class SurfaceCallBack implements SurfaceOps.Callback{ @Override public void surfaceCreated(SurfaceOps surfaceOps) { //初始化相机 initCamera(); } @Override public void surfaceChanged(SurfaceOps surfaceOps,int i,int i1,int i2) { } @Override public void surfaceDestroyed(SurfaceOps surfaceOps) } /第三步:设备创建-根据相机类型创建相机设备对象 private void initCamera(){ CameraKit cameraKit = CameraKit.getInstance(context); String[] cameraList = cameraKit.getCameraIds(); if(cameraList.length > 1) { //摄像头类型:后置摄像头 cameraId = cameraList } CameraStateCallbackImpl cameraStateCallback = new CameraStateCallbackImpl(); cameraKit.createCamera(cameraId,cameraStateCallback,eventHandler); } //第四步:相机回调-触发并通过回调带回Camera对象 , 操作相机设备 private class CameraStateCallbackImpl extends CameraStateCallback{ //创建相机设备@Override public void onCreated(Camera camera) { previewSurface = surfaceProvider.getSurfaceOps().get().getSurface(); if(previewSurface == null){ return; } CameraConfig.Builder builder = camera.getCameraConfigBuilder(); builder.addSurface(previewSurface); camera.configure(builder.build()); cameraSurface = camera; @Override public void onConfigured(Camera camera) { FrameConfig.Builder builder = camera.getFrameConfigBuilder(FRAME_CONFIG_PREVIEW); builder.addSurface(previewSurface); camera.triggerLoopingCapture(builder.build(); } @Override public void onReleased(Camera camera) { super.onReleased(camera); } /第五步:释放相机-关闭相机相关资源 private void releaseCamera(){ if (cameraSurface != null){ cameraSurface.release();
   二.在MainAbilitySlice中创建相机CameraView加载其拍摄预览界面的布局 。   【如何打开后置摄像头的预览界面 摄像头视频预览】import com.saomiao.camera.view.CameraView; import ohos.aafwk.ability.AbilitySlice; import ohos.aafwk.content.Intent; import ohos.agp.components.ComponentContainer; import ohos.agp.components.DirectionalLayout; import ohos.agp.window.dialog.ToastDialog; import ohos.bundle.IBundleManager; public class MainAbilitySlice extends AbilitySlice { public static final int MY_PERMISSIONS_REQUEST_CAMERA = 1039; private CameraView cameraView; @Override public void onStart(Intent intent) { super.onStart(intent); // super.setUIContent(ResourceTable.Layout_ability_main); requestCameraPermission()1.取得相机权限 public void requestCameraPermission(){ if (verifySelfPermission("ohos.permission.CAMERA") != IBundleManager.PERMISSION_GRANTED) { //
ComponentContainer.LayoutConfig.MATCH_PARENT ); cameraView.setLayoutConfig(params); super.setUIContent(cameraView); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }ComponentContainer.LayoutConfig.MATCH_PARENT ); cameraView.setLayoutConfig(params); super.setUIContent(cameraView); } @Override public void onActive() { super.onActive(); } @Override public void onForeground(Intent intent) { super.onForeground(intent); } }
   三.手机USB数据线连接电脑端 , 进行真机测试 , 打开项目的APP检查相机后置摄像头是否允许屏幕拍摄 。   
如何打开后置摄像头的预览界面 摄像头视频预览

文章插图
   若项目如上图所示APP界面打开后 , 预览界面可以正常显示拍摄的东西 , 这意味着手机后置摄像头可以正常拍摄 。
   结语:    我们手机的扫码功能-“扫一扫扫码区域仍在手机后摄像头拍摄的区域 , 必须打开手机拍摄图片 。只有打开手机的拍摄图片 , 我们才能通过扫描功能捕获条形码、二维码等图片信息 。
   由于回调函数的存在Callback初学者需要参考多次使用HarmonyOS相应的官方文档可以更加熟悉 。我已经成功测试了上述所有代码块 。请在成功获得相机权限后添加此代码内容并进行功能测试和优化 。