• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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