327 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
			
		
		
	
	
			327 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
	
	
import camera from '@ohos.multimedia.camera';
 | 
						||
import image from '@ohos.multimedia.image';
 | 
						||
import TopLogo from '../compontents/topLogo';
 | 
						||
 | 
						||
import buffer from '@ohos.buffer';
 | 
						||
 | 
						||
@Component
 | 
						||
export default struct FaceCompare {
 | 
						||
  @State imageBase64: string = 'data:image/jpeg;base64,'
 | 
						||
  private cameraObj: any = null;
 | 
						||
  private cameraManager: any = null;
 | 
						||
  private surfaceId: string = '';
 | 
						||
  private xcomponentController: XComponentController = new XComponentController();
 | 
						||
  // 相机会话
 | 
						||
  private captureSession: any = null;
 | 
						||
  // 相机输入流
 | 
						||
  private cameraInput: any = null;
 | 
						||
  // 预览输出流
 | 
						||
  private previewOutput: any = null;
 | 
						||
  // 拍照输出流
 | 
						||
  private photoOutput: any = null;
 | 
						||
  // 照片接收对象
 | 
						||
  private imageRecever: any = null;
 | 
						||
  private timeSetTimeout: number = 0; //定时器执行次数
 | 
						||
  private timer: any = 0; //定时器
 | 
						||
 | 
						||
  constructor() {
 | 
						||
    super()
 | 
						||
  }
 | 
						||
 | 
						||
  build() {
 | 
						||
    Column() {
 | 
						||
      TopLogo({
 | 
						||
        outFlag: false
 | 
						||
      })
 | 
						||
      Row() {
 | 
						||
        XComponent({
 | 
						||
          id: 'xcomponent',
 | 
						||
          type: 'surface',
 | 
						||
          controller: this.xcomponentController
 | 
						||
        })
 | 
						||
          .onLoad(async () => {
 | 
						||
            this.xcomponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 });
 | 
						||
            this.surfaceId = this.xcomponentController.getXComponentSurfaceId()
 | 
						||
            console.log('jiangsong: xcomponentController this.surfaceId = ' + this.surfaceId)
 | 
						||
            await this.initCamera();
 | 
						||
          })
 | 
						||
          .width('420px')
 | 
						||
          .height('240px')
 | 
						||
      }
 | 
						||
      .backgroundColor(Color.Yellow)
 | 
						||
      .position({ x: 0, y: 0 })
 | 
						||
 | 
						||
      Row() {
 | 
						||
        Text('拍照')
 | 
						||
          .width('100px')
 | 
						||
          .height('55px')
 | 
						||
          .backgroundColor(Color.Blue)
 | 
						||
          .onClick(() => {
 | 
						||
            this.takePhoto()
 | 
						||
          })
 | 
						||
      }
 | 
						||
 | 
						||
      Row() {
 | 
						||
        Image(this.imageBase64)
 | 
						||
          .width(420).height(240).border({ width: 1 })
 | 
						||
      }
 | 
						||
    }
 | 
						||
    .width('100%')
 | 
						||
  }
 | 
						||
 | 
						||
  async aboutToAppear() {
 | 
						||
  }
 | 
						||
 | 
						||
  async aboutToDisappear() {
 | 
						||
    // 停止当前会话
 | 
						||
    this.captureSession.stop()
 | 
						||
    // 释放相机输入流
 | 
						||
    this.cameraInput.close()
 | 
						||
    // 释放预览输出流
 | 
						||
    this.previewOutput.release()
 | 
						||
    // 释放拍照输出流
 | 
						||
    this.photoOutput.release()
 | 
						||
    // 释放会话
 | 
						||
    this.captureSession.release()
 | 
						||
    // 会话置空
 | 
						||
    this.captureSession = null
 | 
						||
  }
 | 
						||
 | 
						||
  async initCamera() {
 | 
						||
    let cameraManager = await camera.getCameraManager(globalThis.context)
 | 
						||
    if (!cameraManager) {
 | 
						||
      console.error("jiangsong camera.getCameraManager error")
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    // 监听相机状态变化
 | 
						||
    cameraManager.on('cameraStatus', (err, cameraStatusInfo) => {
 | 
						||
      console.info(`jiangsong camera : ${cameraStatusInfo.camera.cameraId}`);
 | 
						||
      console.info(`jiangsong status: ${cameraStatusInfo.status}`);
 | 
						||
    })
 | 
						||
 | 
						||
    // 获取相机列表
 | 
						||
    let cameraArray = await cameraManager.getSupportedCameras();
 | 
						||
    if (cameraArray.length <= 0) {
 | 
						||
      console.error("jiangsong cameraManager.getSupportedCameras error")
 | 
						||
      return;
 | 
						||
    }
 | 
						||
 | 
						||
    for (let index = 0; index < cameraArray.length; index++) {
 | 
						||
      console.info('cameraId : ' + cameraArray[index].cameraId); // 获取相机ID
 | 
						||
      console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // 获取相机位置
 | 
						||
      console.info('cameraType : ' + cameraArray[index].cameraType); // 获取相机类型
 | 
						||
      console.info('connectionType : ' + cameraArray[index].connectionType); // 获取相机连接类型
 | 
						||
    }
 | 
						||
 | 
						||
    // 创建相机输入流
 | 
						||
    try {
 | 
						||
      this.cameraInput = cameraManager.createCameraInput(cameraArray[0]);
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to createCameraInput errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
 | 
						||
    // 监听cameraInput错误信息
 | 
						||
    let cameraDevice = cameraArray[0];
 | 
						||
    this.cameraInput.on('error', cameraDevice, (error) => {
 | 
						||
      console.info(`jiangsong Camera input error code: ${error.code}`);
 | 
						||
    })
 | 
						||
 | 
						||
    // 打开相机
 | 
						||
    await this.cameraInput.open((err) => {
 | 
						||
      if (err) {
 | 
						||
        console.error(`jiangsong Failed to open the camera. ${err.code}`);
 | 
						||
        return;
 | 
						||
      }
 | 
						||
      console.log('jiangsong Callback returned with camera opened.');
 | 
						||
    });
 | 
						||
    // 获取相机设备支持的输出流能力
 | 
						||
    let cameraOutputCap = await cameraManager.getSupportedOutputCapability(cameraArray[0]);
 | 
						||
    if (!cameraOutputCap) {
 | 
						||
      console.error("jiangsong cameraManager.getSupportedOutputCapability error")
 | 
						||
      return;
 | 
						||
    }
 | 
						||
    console.info("outputCapability: " + JSON.stringify(cameraOutputCap));
 | 
						||
 | 
						||
    let previewProfilesArray = cameraOutputCap.previewProfiles;
 | 
						||
    if (!previewProfilesArray) {
 | 
						||
      console.error("jiangsong createOutput previewProfilesArray == null || undefined")
 | 
						||
    }
 | 
						||
 | 
						||
    let photoProfilesArray = cameraOutputCap.photoProfiles;
 | 
						||
    if (!photoProfilesArray) {
 | 
						||
      console.error("jiangsong createOutput photoProfilesArray == null || undefined")
 | 
						||
    }
 | 
						||
 | 
						||
 | 
						||
    // 创建预览输出流,其中参数 surfaceId 参考上文 XComponent 组件,预览流为XComponent组件提供的surface
 | 
						||
    try {
 | 
						||
      this.previewOutput = cameraManager.createPreviewOutput(previewProfilesArray[0], this.surfaceId)
 | 
						||
    } catch (error) {
 | 
						||
      console.error("jiangsong Failed to create the PreviewOutput instance.")
 | 
						||
    }
 | 
						||
 | 
						||
    // 监听预览输出错误信息
 | 
						||
    this.previewOutput.on('error', (error) => {
 | 
						||
      console.info(`jiangosng Preview output error code: ${error.code}`);
 | 
						||
    })
 | 
						||
 | 
						||
    // 创建ImageReceiver对象,并设置照片参数:分辨率大小是根据前面 photoProfilesArray 获取的当前设备所支持的拍照分辨率大小去设置
 | 
						||
    this.imageRecever = await image.createImageReceiver(1920, 1080, 4, 8)
 | 
						||
    // 获取照片显示SurfaceId
 | 
						||
    let photoSurfaceId = await this.imageRecever.getReceivingSurfaceId()
 | 
						||
    // 创建拍照输出流
 | 
						||
    try {
 | 
						||
      this.photoOutput = cameraManager.createPhotoOutput(photoProfilesArray[0], photoSurfaceId)
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to createPhotoOutput errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
    //创建会话
 | 
						||
    try {
 | 
						||
      this.captureSession = cameraManager.createCaptureSession()
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to create the CaptureSession instance. errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
 | 
						||
    // 监听session错误信息
 | 
						||
    this.captureSession.on('error', (error) => {
 | 
						||
      console.info(`jiangsong Capture session error code: ${error.code}`);
 | 
						||
    })
 | 
						||
 | 
						||
    // 开始配置会话
 | 
						||
    try {
 | 
						||
      this.captureSession.beginConfig()
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to beginConfig. errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
 | 
						||
    // 向会话中添加相机输入流
 | 
						||
    try {
 | 
						||
      this.captureSession.addInput(this.cameraInput)
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to addInput. errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
 | 
						||
    // 向会话中添加预览输出流
 | 
						||
    try {
 | 
						||
      this.captureSession.addOutput(this.previewOutput)
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to addOutput(previewOutput). errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
 | 
						||
    // 向会话中添加拍照输出流
 | 
						||
    try {
 | 
						||
      this.captureSession.addOutput(this.photoOutput)
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to addOutput(photoOutput). errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
 | 
						||
    // 提交会话配置
 | 
						||
    await this.captureSession.commitConfig()
 | 
						||
 | 
						||
    // 启动会话
 | 
						||
    await this.captureSession.start().then(() => {
 | 
						||
      console.info('jiangsong Promise returned to indicate the session start success.');
 | 
						||
    })
 | 
						||
    // 判断设备是否支持闪光灯
 | 
						||
    let flashStatus
 | 
						||
    try {
 | 
						||
      flashStatus = this.captureSession.hasFlash()
 | 
						||
    } catch (error) {
 | 
						||
      console.error('jiangsong Failed to hasFlash. errorCode = ' + error.code);
 | 
						||
    }
 | 
						||
    console.info('jiangsong Promise returned with the flash light support status:' + flashStatus);
 | 
						||
 | 
						||
    if (flashStatus) {
 | 
						||
      // 判断是否支持自动闪光灯模式
 | 
						||
      let flashModeStatus
 | 
						||
      try {
 | 
						||
        let status = this.captureSession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO)
 | 
						||
        flashModeStatus = status
 | 
						||
      } catch (error) {
 | 
						||
        console.error('jiangsong Failed to check whether the flash mode is supported. errorCode = ' + error.code);
 | 
						||
      }
 | 
						||
      if (flashModeStatus) {
 | 
						||
        // 设置自动闪光灯模式
 | 
						||
        try {
 | 
						||
          this.captureSession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO)
 | 
						||
        } catch (error) {
 | 
						||
          console.error('jiangsong Failed to set the flash mode. errorCode = ' + error.code);
 | 
						||
        }
 | 
						||
      }
 | 
						||
    }
 | 
						||
  }
 | 
						||
 | 
						||
  takePhoto() {
 | 
						||
    let settings = {
 | 
						||
      quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高
 | 
						||
      rotation: camera.ImageRotation.ROTATION_0                                            // 设置图片旋转角度0
 | 
						||
    }
 | 
						||
    // 使用当前拍照设置进行拍照
 | 
						||
    this.photoOutput.capture(settings, async (err) => {
 | 
						||
      if (err) {
 | 
						||
        console.error(`jiangsong Failed to capture the photo ${err.message}` + JSON.stringify(err));
 | 
						||
        return;
 | 
						||
      }
 | 
						||
      console.info('jiangsong Callback invoked to indicate the photo capture request success.');
 | 
						||
 | 
						||
      this.imageRecever.getReceivingSurfaceId().then(id => {
 | 
						||
        console.log('jiangsong getReceivingSurfaceId succeeded.');
 | 
						||
      }).catch(error => {
 | 
						||
        console.log('jiangsong getReceivingSurfaceId failed.');
 | 
						||
      })
 | 
						||
 | 
						||
      this.getPhoto();
 | 
						||
      this.timeSetTimeout = 0;
 | 
						||
      clearTimeout(this.timer);
 | 
						||
    });
 | 
						||
  }
 | 
						||
 | 
						||
  getPhoto() {
 | 
						||
    this.imageRecever.readLatestImage((err, img) => {
 | 
						||
      if (err) {
 | 
						||
        console.log('jiangsong readLatestImage failed.' + JSON.stringify((err)));
 | 
						||
        this.timeSetTimeout++;
 | 
						||
        if (this.timeSetTimeout > 20) {
 | 
						||
          return;
 | 
						||
        }
 | 
						||
        this.timer = setTimeout(() => {
 | 
						||
          this.getPhoto()
 | 
						||
        }, 300)
 | 
						||
      } else {
 | 
						||
        console.log('jiangsong img.clipRect.' + JSON.stringify(img.clipRect));
 | 
						||
 | 
						||
        img.getComponent(4, (err, component) => {
 | 
						||
          if (err) {
 | 
						||
            console.log('jiangsong getComponent failed.' + JSON.stringify(err));
 | 
						||
          } else {
 | 
						||
 | 
						||
            const imagePackerApi = image.createImagePacker();
 | 
						||
            let packOpts = { format: "image/jpeg", quality: 98 };
 | 
						||
 | 
						||
            let buf = buffer.from(component.byteBuffer);
 | 
						||
            let str = buf.toString('base64')
 | 
						||
            this.imageBase64 = this.imageBase64 + str
 | 
						||
            // console.error('jiangsong this.imageBase64.length: ' + this.imageBase64.length);
 | 
						||
            // console.error('jiangsong this.imageBase64.length: ' + this.imageBase64.slice(1, 100));
 | 
						||
            //
 | 
						||
            // const imageSource = image.createImageSource(component.byteBuffer);
 | 
						||
            // imagePackerApi.packing(imageSource, packOpts).then(async data => {
 | 
						||
            //   console.log('jiangsong encodeToStringSync data.' + typeof data);
 | 
						||
            //   // let res = await writeFile({
 | 
						||
            //   //   fileName: '/test.jpg',
 | 
						||
            //   //   buffer: data
 | 
						||
            //   // });
 | 
						||
            //
 | 
						||
            //   let buf = buffer.from(data);
 | 
						||
            //   let str = buf.toString('base64')
 | 
						||
            //   this.imageBase64 = this.imageBase64 + str
 | 
						||
            // }).catch(error => {
 | 
						||
            //   console.error('jiangsong Failed to pack the image. And the error is: ' + error);
 | 
						||
            // })
 | 
						||
          }
 | 
						||
        })
 | 
						||
      }
 | 
						||
    });
 | 
						||
  }
 | 
						||
}
 |