参考demo:import { abilityAccessCtrl, PermissionRequestResult, Permissions } from '@kit.AbilityKit'; import { BusinessError } from '@kit.BasicServicesKit'; import { image } from '@kit.ImageKit'; import { camera } from '@kit.CameraKit'; import fs from '@ohos.file.fs' const TAG = '[PhotoDemo]'; @Entry @Component struct PhotoPage { context: Context = getContext(this) as Context; @State finalPixelMap: image.PixelMap | undefined = undefined; @State buffer: ArrayBuffer | undefined = undefined; @State surfaceId: string = ''; @State imageSize: image.Size = { width: 320, height: 480 }; private mXComponentController: XComponentController = new XComponentController; private cameraManager: camera.CameraManager | undefined = undefined; private cameraInput: camera.CameraInput | undefined = undefined; private photoOutput: camera.PhotoOutput | undefined = undefined; private previewOutput: camera.PreviewOutput | undefined = undefined; private cameraSession: camera.PhotoSession | undefined = undefined; aboutToAppear(): void { let permissions: Array<Permissions> = [ 'ohos.permission.CAMERA', 'ohos.permission.WRITE_MEDIA', 'ohos.permission.READ_MEDIA', 'ohos.permission.MEDIA_LOCATION' ]; setTimeout(async () => { await this.prepareCamera(); }, 500); let atManager: abilityAccessCtrl.AtManager = abilityAccessCtrl.createAtManager(); // requestPermissionsFromUser会判断权限的授权状态来决定是否唤起弹窗 atManager.requestPermissionsFromUser(this.context, permissions).then((data: PermissionRequestResult) => { let grantStatus: Array<number> = data.authResults; let length: number = grantStatus.length; for (let i = 0; i < length; i++) { if (grantStatus[i] != 0) { // 用户拒绝授权,提示用户必须授权才能访问当前页面的功能,并引导用户到系统设置中打开相应的权限 return; } } console.info(`${TAG} Success to request permissions from user. authResults is ${grantStatus}.`); setTimeout(async () => { await this.prepareCamera(); }, 500); }).catch((err: BusinessError) => { console.error(`${TAG} Failed to request permissions from user. Code is ${err.code}, message is ${err.message}`); }) } build() { Column() { //预览框 Column({ space: 20 }) { Row() { XComponent({ id: '', type: 'surface', libraryname: '', controller: this.mXComponentController }) .onLoad(() => { // 设置Surface宽高(1920*1080),预览尺寸设置参考previewProfilesArray获取的当前设备所支持的预览分辨率大小去设置 // 预览流与录像输出流的分辨率的宽高比要保持一致 this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 320, surfaceHeight: 480 }); // 获取Surface ID this.surfaceId = this.mXComponentController.getXComponentSurfaceId(); setTimeout(async () => { await this.prepareCamera(); }, 500); }) .height(400) } Button('拍照') .width(200) .height(30) .onClick(async () => { this.takePhoto() }) if (this.finalPixelMap !== undefined) { Image(this.finalPixelMap) .objectFit(ImageFit.Fill) .width('100%') .height(300) } } .width('100%') .height('100%') .padding(15) .borderRadius(8) } .width('100%') .height('100%') .backgroundColor('#FFFFFF') } async takePhoto() { //设置拍照参数 let photoCaptureSetting: camera.PhotoCaptureSetting = { quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高 rotation: camera.ImageRotation.ROTATION_0 // 设置图片旋转角度0 } //通过拍照流实现:点击拍照 await this.photoOutput?.capture(photoCaptureSetting).catch((error: BusinessError) => { console.error(`CameraDemo Failed to capture the photo ${error.message}`); //不符合条件则进入 }) } photoPackToFile() { const context: Context = getContext(this); const path: string = context.cacheDir + "/pixel_map.jpg"; let file = fs.openSync(path, fs.OpenMode.CREATE | fs.OpenMode.READ_WRITE); const imagePackerApi = image.createImagePacker(); let packOpts: image.PackingOption = { format: "image/jpeg", quality: 98 }; imagePackerApi.packToFile(this.finalPixelMap, file.fd, packOpts).then(() => { // 直接打包进文件 // CLogE(file.path) }).catch((error: BusinessError) => { console.error('Failed to pack the image. And the error is: ' + error); }) } // 创建CameraManager对象 createCameraManager() { let cameraManager: camera.CameraManager = camera.getCameraManager(this.context); if (!cameraManager) { console.error('CameraDemo camera.getCameraManager error'); return; } this.cameraManager = cameraManager; // 监听相机状态变化 this.cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => { console.info(`CameraDemo camera: ${cameraStatusInfo.camera.cameraId}, status: ${cameraStatusInfo.status}`); }); } //函数中设置监听photoAvailable,在回调中生成图片 setPhotoOutputCb(photoOutput: camera.PhotoOutput) { //设置回调之后,调用photoOutput的capture方法,就会将拍照的buffer回传到回调中 photoOutput.on('photoAvailable', (errCode: BusinessError, photo: camera.Photo): void => { console.info(`CameraDemo getPhoto start. err: ${JSON.stringify(errCode)}`); if (errCode || photo === undefined || photo.main === undefined) { console.error('CameraDemo getPhoto failed'); return; } let imageObj = photo.main; imageObj.getComponent(image.ComponentType.JPEG, async (errCode: BusinessError, component: image.Component): Promise<void> => { console.info('CameraDemo getComponent start'); if (errCode || component === undefined) { console.error('CameraDemo getComponent failed'); return; } let buffer: ArrayBuffer; if (component.byteBuffer) { buffer = component.byteBuffer; this.buffer = buffer; let sourceOptions: image.SourceOptions = { sourceDensity: 0, // 在不确定当前密度时传0 sourcePixelFormat: image.PixelMapFormat.RGBA_8888, sourceSize: this.imageSize } let imageSource: image.ImageSource = image.createImageSource(buffer, sourceOptions); let opts: image.InitializationOptions = { editable: false, pixelFormat: image.PixelMapFormat.RGBA_8888, size: this.imageSize } let pixelMap = await imageSource.createPixelMap(opts); this.finalPixelMap = pixelMap; this.photoPackToFile(); } else { console.error('CameraDemo byteBuffer is null'); return; } }); }); } //相机准备 async prepareCamera() { this.createCameraManager(); if (!this.cameraManager) { console.error('CameraDemo cameraManager is undefined.') return; } // 获取设备支持的相机对象,根据位置可划分后置,前置,折叠态相机 let cameraDevices: Array<camera.CameraDevice> = []; try { cameraDevices = this.cameraManager.getSupportedCameras(); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo The getSupportedCameras call failed. error: ${JSON.stringify(err)}`) } cameraDevices.forEach((cameraDevice: camera.CameraDevice) => { console.info(`CameraDemo cameraId: ${cameraDevice.cameraId}, cameraPosition: ${cameraDevice.cameraPosition.toString()}, cameraType: ${cameraDevice.cameraType.toString()}, connectionType: ${cameraDevice.connectionType.toString()}`) }) // 获取设备支持的具体某个相机对象的支持的模式类型,包含普通拍照及普通录像两种模式,cameraDevices[0]代表后置相机 let cameraSceneModes: Array<camera.SceneMode> = []; try { cameraSceneModes = this.cameraManager.getSupportedSceneModes(cameraDevices[1]); cameraSceneModes.forEach((cameraSceneMode: camera.SceneMode) => { console.info(`CameraDemo cameraSceneMode: ${cameraSceneMode.toString()}`) }) //判断支持的模式类型是否包含拍照 let isSupportPhotoMode: boolean = cameraSceneModes.indexOf(camera.SceneMode.NORMAL_PHOTO) >= 0; if (!isSupportPhotoMode) { console.error('CameraDemo photo mode not support'); return; } } catch (error) { let err = error as BusinessError; console.error(`CameraDemo The getSupportedSceneModes call failed. error: ${JSON.stringify(err)}`) } // 创建相机输入流 try { this.cameraInput = this.cameraManager.createCameraInput(cameraDevices[1]); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo createCaptureSession error. error: ${JSON.stringify(err)}`); return } // 监听cameraInput错误信息 this.cameraInput.on('error', cameraDevices[1], (error: BusinessError) => { console.error(`CameraDemo Camera input error: ${JSON.stringify(error)}`); }); // 打开相机 try { await this.cameraInput.open(); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo cameraInput open error. error: ${JSON.stringify(err)}`); } // 获取相机对象支持的输出流能力,包含预览,拍照,录像等信息 let cameraOutputCapability: camera.CameraOutputCapability = this.cameraManager.getSupportedOutputCapability(cameraDevices[1], camera.SceneMode.NORMAL_PHOTO) if (!cameraOutputCapability) { console.error('CameraDemo cameraManager.getSupportedOutputCapability error'); return; } // //获取当前设备支持的预览能力 let previewProfile = cameraOutputCapability.previewProfiles[0]; //预览流和相片分辨率的宽高比要保持一致 cameraOutputCapability.previewProfiles.forEach((profile) => { if (profile.size.width == this.imageSize.width && profile.size.height == this.imageSize.height) { previewProfile = profile; return; } }) this.imageSize = previewProfile.size; // 创建相机预览输出流 try { this.previewOutput = this.cameraManager.createPreviewOutput(previewProfile, this.surfaceId); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo createCaptureSession error. error: ${JSON.stringify(err)}`); return } // 监听previewOutput错误信息 this.previewOutput.on('error', (error: BusinessError) => { console.error(`CameraDemo previewOutput error: ${JSON.stringify(error)}`); }); try { //获取当前设备支持的拍照能力 let photoProfile = cameraOutputCapability.photoProfiles[0]; //拍照流和相片分辨率的宽高比要保持一致 cameraOutputCapability.photoProfiles.forEach((profile) => { if (profile.size.width == this.imageSize.width && profile.size.height == this.imageSize.height) { photoProfile = profile; return; } }) //创建相机拍照输出流 this.photoOutput = this.cameraManager.createPhotoOutput(photoProfile); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo createPhotoOutput error ${JSON.stringify(err)}`); } if (this.photoOutput === undefined) { console.error('CameraDemo photoOutput is undefined.'); return; } //调用自定义函数,在定义的监听的回调中保存图片,该自定义函数需传参拍照输出流 this.setPhotoOutputCb(this.photoOutput); //创建相机会话 try { this.cameraSession = this.cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession; } catch (error) { let err = error as BusinessError; console.error(`CameraDemo createCaptureSession error. error: ${JSON.stringify(err)}`); return } // 监听session错误信息 this.cameraSession.on('error', (error: BusinessError) => { console.error(`CameraDemo Capture session error: ${JSON.stringify(error)}`); }); // 开始配置会话 try { this.cameraSession.beginConfig() } catch (error) { let err = error as BusinessError; console.error(`CameraDemo beginConfig error. error: ${JSON.stringify(err)}`); } // 向会话中添加相机输入流 try { this.cameraSession.addInput(this.cameraInput) } catch (error) { let err = error as BusinessError; console.error(`CameraDemo addInput error. error: ${JSON.stringify(err)}`); } // 向会话中添加预览输出流 try { this.cameraSession.addOutput(this.previewOutput) } catch (error) { let err = error as BusinessError; console.error(`CameraDemo add previewOutput error. error: ${JSON.stringify(err)}`); } // 向会话中添加拍照输出流 try { this.cameraSession.addOutput(this.photoOutput); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo add photoOutput error. error: ${JSON.stringify(err)}`); } // 提交会话配置 try { await this.cameraSession.commitConfig(); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo captureSession commitConfig error: ${JSON.stringify(err)}`); } // 启动会话 try { await this.cameraSession.start(); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo captureSession start error: ${JSON.stringify(err)}`); } //调用自定义函数,配置相机的参数,传参相机会话 this.configuringSession(this.cameraSession) } //配置相机的参数可以调整拍照的一些功能,包括闪光灯、变焦、焦距等 configuringSession(photoSession: camera.PhotoSession): void { // 判断设备是否支持闪光灯 let flashStatus: boolean = false; try { flashStatus = photoSession.hasFlash(); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo Failed to hasFlash. error: ${JSON.stringify(err)}`); } console.info(`CameraDemo Returned with the flash light support status: ${flashStatus}`); if (flashStatus) { // 判断是否支持自动闪光灯模式 let flashModeStatus: boolean = false; try { let status: boolean = photoSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO); flashModeStatus = status; } catch (error) { let err = error as BusinessError; console.error(`CameraDemo Failed to check whether the flash mode is supported. error: ${JSON.stringify(err)}`); } if (flashModeStatus) { // 设置自动闪光灯模式 try { photoSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo Failed to set the flash mode. error: ${JSON.stringify(err)}`); } } } // 判断是否支持连续自动变焦模式 let focusModeStatus: boolean = false; try { let status: boolean = photoSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); focusModeStatus = status; } catch (error) { let err = error as BusinessError; console.error(`CameraDemo Failed to check whether the focus mode is supported. error: ${JSON.stringify(err)}`); } if (focusModeStatus) { // 设置连续自动变焦模式 try { photoSession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo Failed to set the focus mode. error: ${JSON.stringify(err)}`); } } // 获取相机支持的可变焦距比范围 let zoomRatioRange: Array<number> = []; try { zoomRatioRange = photoSession.getZoomRatioRange(); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo Failed to get the zoom ratio range. error: ${JSON.stringify(err)}`); } if (zoomRatioRange.length <= 0) { return; } // 设置可变焦距比 try { photoSession.setZoomRatio(zoomRatioRange[0]); } catch (error) { let err = error as BusinessError; console.error(`CameraDemo Failed to set the zoom ratio value. error: ${JSON.stringify(err)}`); } } }
参考demo: