1/* 2 * Copyright (c) 2023 Hunan OpenValley Digital Industry Development Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16import camera from '@ohos.multimedia.camera'; 17import images from '@ohos.multimedia.image'; 18import emitter from '@ohos.events.emitter'; 19import image from '@ohos.multimedia.image'; 20import { BusinessError } from '@ohos.base'; 21import Logger from '../utils/Logger'; 22import QRCode, { ImageWH } from '../utils/DeCode'; 23 24// 相机宽高 25interface CameraWH{ 26 width: number, 27 height: number 28}; 29const FOUR: number = 4; // format 30const EIGHT: number = 8; // capacity 31const FOUR_THOUSAND_AND_SIXTY_NINE: number = 4096; // buffer大小 32const cameraWH: CameraWH = { 33 width: 480, 34 height: 640 35}; 36const TAG = '[CameraModel]'; 37 38export default class CameraService { 39 private cameraMgr?: camera.CameraManager; 40 private camerasArray?: Array<camera.CameraDevice>; 41 private cameraInput?: camera.CameraInput; 42 private previewOutput?: camera.PreviewOutput; 43 private photoOutPut?: camera.PhotoOutput; 44 private capSession?: camera.CaptureSession; 45 private videoOutput?: camera.VideoOutput; 46 private capability?: camera.CameraOutputCapability; 47 private receiver?: images.ImageReceiver; 48 private pixelMap?: images.PixelMap; 49 private idInterval: number = -1; 50 51 constructor() { 52 this.receiver = images.createImageReceiver( 53 cameraWH.width, 54 cameraWH.height, 55 FOUR, 56 EIGHT 57 ); 58 Logger.info(TAG, 'createImageReceiver'); 59 this.receiver?.on('imageArrival', () => { 60 Logger.info(TAG, 'imageArrival'); 61 this.receiver?.readNextImage((err: BusinessError, image: image.Image) => { 62 Logger.info(TAG, 'readNextImage image:' + JSON.stringify(image.size)); 63 if (err || image === undefined) { 64 Logger.error(TAG, 'failed to get valid image'); 65 return; 66 } 67 image.getComponent(FOUR, async (errMsg: BusinessError, img: image.Component) => { 68 Logger.info(TAG, 'getComponent'); 69 Logger.info(TAG, 'img.byteBuffer ' + img.byteBuffer.byteLength); 70 if (errMsg || img === undefined) { 71 Logger.info(TAG, 'failed to get valid buffer'); 72 return; 73 } 74 let buffer: ArrayBuffer = new ArrayBuffer(FOUR_THOUSAND_AND_SIXTY_NINE); 75 if (img.byteBuffer) { 76 buffer = img.byteBuffer; 77 Logger.info(TAG, 'buffer==' + buffer.byteLength); 78 let imageSourceApi: image.ImageSource = images.createImageSource(buffer); 79 this.pixelMap = await imageSourceApi.createPixelMap(); 80 let imageInfo: image.ImageInfo = await this.pixelMap?.getImageInfo(); 81 let w: number = imageInfo.size.width; 82 let h: number = imageInfo.size.height; 83 Logger.info(TAG, 'imageInfo==w==' + w); 84 Logger.info(TAG, 'imageInfo==h==' + h); 85 Logger.info(TAG, 'imageInfo.density==h==' + imageInfo.density); 86 this.scanCode(w, h) 87 } else { 88 Logger.error(TAG, 'img.byteBuffer is undefined'); 89 } 90 image.release(); 91 }); 92 }); 93 }); 94 } 95 96 /** 97 * 扫描二维码 98 * @param w,h 99 */ 100 async scanCode(w: number, h: number) { 101 try { 102 let qrCode: QRCode = new QRCode(); 103 let wh: ImageWH = { 104 width: w, 105 height: h 106 } 107 let text: string = await qrCode.decode(this.pixelMap as image.PixelMap, wh); 108 Logger.info(TAG, 'text==JSON.stringify===' + JSON.stringify(text)) 109 Logger.info(TAG, 'text=====' + text) 110 let eventDataText: emitter.EventData = { 111 data: { 112 'text': text 113 } 114 }; 115 let innerEventText: emitter.InnerEvent = { 116 eventId: 1, 117 priority: emitter.EventPriority.IMMEDIATE 118 }; 119 Logger.info(TAG, 'emit=====before') 120 emitter.emit(innerEventText, eventDataText); 121 Logger.info(TAG, 'emit=====after') 122 } catch (err) { 123 Logger.info(TAG, 'err=====err' + err) 124 this.takePicture(); 125 } 126 } 127 128 /** 129 * 初始化相机 130 * @param surfaceId 131 */ 132 async initCamera(surfaceId: string): Promise<void> { 133 Logger.info(TAG, `initCamera surfaceId:${surfaceId}`); 134 await this.cameraRelease(); 135 Logger.info(TAG, `initCamera this.cameraRelease surfaceId:${surfaceId}`); 136 Logger.info(TAG, 'getCameraManager begin'); 137 try { 138 Logger.info(TAG, 'getCameraManager try begin'); 139 this.cameraMgr = camera.getCameraManager(AppStorage.get('cameraContext')); 140 Logger.info(TAG, 'getCameraManager try end'); 141 } catch (e) { 142 Logger.info(TAG, `getCameraManager catch e:${JSON.stringify(e)}`); 143 Logger.info(TAG, `getCameraManager catch code:${JSON.stringify(e.code)}`); 144 Logger.info(TAG, `getCameraManager catch message:${JSON.stringify(e.message)}`); 145 } 146 Logger.info(TAG, 'getCameraManager end'); 147 Logger.info(TAG, `getCameraManager ${JSON.stringify(this.cameraMgr)}`); 148 this.camerasArray = this.cameraMgr?.getSupportedCameras(); 149 Logger.info(TAG, `get cameras ${this.camerasArray?.length}`); 150 if (this.camerasArray?.length === 0) { 151 Logger.info(TAG, 'cannot get cameras'); 152 return; 153 } 154 155 let mCamera = this.camerasArray && this.camerasArray[0] as camera.CameraDevice; 156 this.cameraInput = this.cameraMgr?.createCameraInput(mCamera); 157 this.cameraInput?.open(); 158 Logger.info(TAG, 'createCameraInput'); 159 this.capability = this.cameraMgr?.getSupportedOutputCapability(mCamera); 160 let previewProfile = this.capability?.previewProfiles[0]; 161 this.previewOutput = this.cameraMgr?.createPreviewOutput( 162 previewProfile, 163 surfaceId 164 ); 165 166 Logger.info(TAG, 'createPreviewOutput'); 167 let rSurfaceId = await this.receiver?.getReceivingSurfaceId(); 168 let photoProfile = this.capability?.photoProfiles[0]; 169 this.photoOutPut = this.cameraMgr?.createPhotoOutput( 170 photoProfile, 171 rSurfaceId 172 ); 173 174 this.capSession = this.cameraMgr?.createCaptureSession(); 175 Logger.info(TAG, 'createCaptureSession'); 176 this.capSession?.beginConfig(); 177 Logger.info(TAG, 'beginConfig'); 178 this.capSession?.addInput(this.cameraInput); 179 this.capSession?.addOutput(this.previewOutput); 180 this.capSession?.addOutput(this.photoOutPut); 181 await this.capSession?.commitConfig(); 182 await this.capSession?.start(); 183 Logger.info(TAG, 'captureSession start'); 184 this.takePicture(); 185 } 186 187 /** 188 * 拍照 189 */ 190 async takePicture() { 191 Logger.info(TAG, 'takePicture'); 192 let photoSettings: camera.PhotoCaptureSetting = { 193 rotation: 0, 194 quality: camera.QualityLevel.QUALITY_LEVEL_MEDIUM, 195 location: { 196 // 位置信息,经纬度 197 latitude: 12.9698, 198 longitude: 77.75, 199 altitude: 1000 200 }, 201 mirror: false, 202 }; 203 try { 204 this.photoOutPut?.capture(photoSettings); 205 } catch (e) { 206 Logger.error(TAG, 'takePicture err:' + e); 207 } 208 Logger.info(TAG, 'takePicture done'); 209 } 210 211 /** 212 * 资源释放 213 */ 214 async cameraRelease(): Promise<void> { 215 Logger.info(TAG, 'releaseCamera'); 216 if (this.idInterval !== -1) { 217 Logger.info(TAG, 'clearInterval idInterval'); 218 clearInterval(this.idInterval); 219 this.idInterval = -1; 220 } 221 if (this.cameraInput) { 222 await this.cameraInput?.close(); 223 this.cameraInput = undefined; 224 } 225 if (this.previewOutput) { 226 await this.previewOutput?.release(); 227 this.previewOutput = undefined; 228 } 229 if (this.photoOutPut) { 230 await this.photoOutPut?.release(); 231 this.photoOutPut = undefined; 232 } 233 if (this.videoOutput) { 234 await this.videoOutput?.release(); 235 this.videoOutput = undefined; 236 } 237 if (this.capSession) { 238 await this.capSession?.release(); 239 this.capSession = undefined; 240 } 241 } 242} 243 244