• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/*
2 * Copyright (c) 2022 Huawei Device 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 */
15import prompt from '@ohos.prompt'
16import Logger from '../model/Logger'
17import CameraService from '../model/CameraService'
18import TitleBar from '../view/TitleBar'
19
20const CameraMode = {
21  MODE_PHOTO: 0, // 拍照模式
22  MODE_VIDEO: 1 // 录像模式
23}
24
25@Entry
26@Component
27struct CameraPage {
28  private tag: string = 'CameraPage'
29  private mXComponentController: XComponentController = new XComponentController()
30  private surfaceId: number = -1
31  private cameraService: CameraService = new CameraService(getContext(this))
32  @State imgThumbnail: string = ''
33  @State videoThumbnail: Resource | undefined = undefined
34  @State curModel: number = CameraMode.MODE_PHOTO
35  @State isRecording: boolean = false
36
37  aboutToAppear() {
38    this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
39    Logger.info(this.tag, `aboutToAppear,surfaceId=${this.surfaceId}`)
40    this.cameraService.setTakePictureCallback(this.handleTakePicture.bind(this))
41  }
42
43  getCameraIcon() {
44    if (this.curModel === CameraMode.MODE_PHOTO) {
45      return $r('app.media.take_photo_normal')
46    } else {
47      if (this.isRecording) {
48        return $r('app.media.take_video_stop')
49      } else {
50        return $r('app.media.take_video_normal')
51      }
52    }
53  }
54
55  refreshVideoState() {
56    if (this.isRecording) {
57      Logger.info(this.tag, 'stopVideo begin')
58      this.cameraService.stopVideo()
59      this.isRecording = false
60      this.videoThumbnail = $r('app.media.video_poster')
61    } else {
62      Logger.info(this.tag, 'startVideo begin')
63      this.cameraService.startVideo()
64      this.isRecording = true
65    }
66  }
67
68  handleTakePicture = (thumbnail: string) => {
69    this.imgThumbnail = thumbnail
70    Logger.info(this.tag, `takePicture end , thumbnail: ${this.imgThumbnail}`)
71  }
72
73  build() {
74    Column() {
75      TitleBar()
76      Stack({ alignContent: Alignment.Bottom }) {
77        XComponent({
78          id: 'componentId',
79          type: 'surface',
80          controller: this.mXComponentController
81        })
82          .onLoad(() => {
83            Logger.info(this.tag, 'onLoad is called')
84            this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 })
85            this.surfaceId = this.mXComponentController.getXComponentSurfaceId()
86            Logger.info(this.tag, `onLoad surfaceId: ${this.surfaceId}`)
87            this.curModel = CameraMode.MODE_PHOTO
88            this.cameraService.initCamera(this.surfaceId)
89          })
90          .height('100%')
91          .width('100%')
92          .margin({ bottom: 130 })
93        Column() {
94          Row() {
95            Text($r('app.string.photo'))
96              .fontColor(this.curModel === CameraMode.MODE_PHOTO ? Color.White : Color.Gray)
97              .fontSize(25)
98              .onClick(() => {
99                if (this.curModel === CameraMode.MODE_VIDEO) {
100                  prompt.showToast({ message: '切换中...', duration: 1000 })
101                  if (this.isRecording) {
102                    this.cameraService.stopVideo()
103                    this.isRecording = false
104                  }
105                  this.curModel = CameraMode.MODE_PHOTO
106                  setTimeout(() => {
107                    this.cameraService.initCamera(this.surfaceId)
108                  }, 500)
109                  this.videoThumbnail = undefined
110                }
111              })
112            Text($r('app.string.video'))
113              .fontColor(this.curModel === CameraMode.MODE_VIDEO ? Color.White : Color.Gray)
114              .fontSize(25)
115              .margin({ left: 30 })
116              .onClick(() => {
117                if (this.curModel === CameraMode.MODE_PHOTO) {
118                  prompt.showToast({ message: '切换中...', duration: 1000 })
119                  this.curModel = CameraMode.MODE_VIDEO
120                  this.cameraService.initCamera(this.surfaceId)
121                }
122              })
123          }
124          .size({ height: 40, width: '100%' })
125          .margin({ left: 50 })
126          .justifyContent(FlexAlign.Center)
127
128          Row() {
129            if (this.curModel === CameraMode.MODE_VIDEO) {
130              Image(this.videoThumbnail)
131                .size({ width: 70, height: 70 })
132                .aspectRatio(1)
133                .borderRadius(40)
134                .objectFit(ImageFit.Fill)
135                .backgroundColor(Color.Gray)
136            } else {
137              Image(this.imgThumbnail)
138                .size({ width: 70, height: 70 })
139                .aspectRatio(1)
140                .borderRadius(40)
141                .objectFit(ImageFit.Fill)
142                .backgroundColor(Color.Gray)
143            }
144
145            Image(this.getCameraIcon())
146              .size({ width: 70, height: 70 })
147              .margin({ left: 50 })
148              .key('photo')
149              .onClick(() => {
150                if (this.curModel === CameraMode.MODE_PHOTO) {
151                  Logger.info(this.tag, 'takePicture begin')
152                  prompt.showToast({ message: '拍照中...', duration: 1000 })
153                  this.cameraService.takePicture()
154                } else if (this.curModel === CameraMode.MODE_VIDEO) {
155                  this.refreshVideoState()
156                }
157              })
158          }
159          .size({ height: 80, width: '100%' })
160          .margin({ right: 50 })
161          .justifyContent(FlexAlign.Center)
162        }
163        .size({ height: 130, width: '100%' })
164        .padding({ bottom: 10 })
165        .backgroundColor(Color.Black)
166      }
167      .width('100%')
168      .height('100%')
169      .layoutWeight(1)
170      .backgroundColor(Color.Grey)
171    }
172    .width('100%')
173    .height('100%')
174  }
175
176  async aboutToDisappear() {
177    if (this.isRecording) {
178      await this.cameraService.stopVideo()
179    }
180    await this.cameraService.releaseCamera()
181  }
182}