提交 8f9059c7 编写于 作者: W wangqingkaihong

检视修改

Signed-off-by: Nwangqingkaihong <wangqing@kaihong.com>
上级 0196fee3
...@@ -8,10 +8,16 @@ ...@@ -8,10 +8,16 @@
本例效果如下: 本例效果如下:
![contactlist](figures/camera.png) | 拍照 | 预览 |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
| <img src="figures/camera.png" alt="contactlist" style="zoom: 45%;" /> | <img src="figures/camerapreview.gif" alt="contactlist" style="zoom: 50%;" /> |
## 运行环境 ## 运行环境
本例基于以下环境开发,开发者也可以基于其他适配的版本进行开发。
- IDE:DevEco Studio 4.0.0.201 Beta1 - IDE:DevEco Studio 4.0.0.201 Beta1
- SDK:Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1) - SDK:Ohos_sdk_public 4.0.7.5 (API Version 10 Beta1)
...@@ -19,222 +25,224 @@ ...@@ -19,222 +25,224 @@
本例使用@ohos.multimedia.camera接口实现相机示例的主要功能:拍照、预览; 本例使用@ohos.multimedia.camera接口实现相机示例的主要功能:拍照、预览;
使用@ohos.multimedia.image接口实现图片接收; - 拍照:XComponent组件负责绘制摄像头画面呈现的窗口,其onload事件调用cameraModel.ts的initCamera方法初始化相机功能输出画面信息。拍照动作使用Image组件实现,其onclick事件调用cameraModel.ts的takepicture方法开始拍照。
使用@ohos.multimedia.mediaLibrary接口实现对媒体文件的存储。
- XComponent组件负责绘制摄像头画面呈现的窗口,其onload事件调用cameraModel.ts的initCamera方法初始化相机功能输出预览信息。 - 预览:返回相机界面点击底部左侧预览图可进入相册应用,可以在其中查看照片和录制的视频。
- 拍照按钮:使用Image组件实现,其onclick事件调用cameraModel.ts的takepicture方法开始拍照。
- 照片存储:MediaModel.ts中的createAndGetUri方法通过引用自@ohos.multimedia.mediaLibrary的mediaLibraryTest类创建媒体资源,saveImage方法将拍摄的照片写入到Mediamodel传回的资源中去。
## 开发步骤 ## 开发步骤
1.申请所需权限 1. 申请所需权限
​ 在model.json5中添加以下配置: 在model.json5中添加以下配置:
```json ```json
"requestPermissions": [ "requestPermissions": [
{ {
"name": "ohos.permission.CAMERA"//允许应用使用相机拍摄照片和录制视频 "name": "ohos.permission.CAMERA"//允许应用使用相机拍摄照片和录制视频
}, },
{ {
"name": "ohos.permission.MICROPHONE"//允许应用使用麦克风 "name": "ohos.permission.MICROPHONE"//允许应用使用麦克风
}, },
{ {
"name": "ohos.permission.MEDIA_LOCATION"//允许应用访问用户媒体文件中的地理位置信息 "name": "ohos.permission.MEDIA_LOCATION"//允许应用访问用户媒体文件中的地理位置信息
}, },
{ {
"name": "ohos.permission.WRITE_MEDIA"//允许应用读写用户外部存储中的媒体文件信息 "name": "ohos.permission.WRITE_MEDIA"//允许应用读写用户外部存储中的媒体文件信息
}, },
{ {
"name": "ohos.permission.READ_MEDIA"//允许应用读取用户外部存储中的媒体文件信息 "name": "ohos.permission.READ_MEDIA"//允许应用读取用户外部存储中的媒体文件信息
} }
] ]
``` ```
2.创建绘制组件XComponent 2. 创建绘制组件XComponent以输出摄像头获取的画面,其绑定的onload方法中设定了画幅的大小。
```typescript ```typescript
build() { build() {
Column() { Column() {
Title() Title()
.visibility(this.isTitleShow ? Visibility.Visible : Visibility.None) .visibility(this.isTitleShow ? Visibility.Visible : Visibility.None)
Stack({ alignContent: Alignment.Bottom }) { Stack({ alignContent: Alignment.Bottom }) {
Stack({ alignContent: Alignment.TopStart }) { Stack({ alignContent: Alignment.TopStart }) {
XComponent({ XComponent({
id: 'componentId', id: 'componentId',
type: 'surface', type: 'surface',
controller: this.mXComponentController //将控制器绑定至XComponent组件 controller: this.mXComponentController //将控制器绑定至XComponent组件
}) })
.onLoad(() => { .onLoad(() => {
this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 });//设置surface大小 this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 640, surfaceHeight: 480 });//设置surface大小
this.surfaceId = this.mXComponentController.getXComponentSurfaceId(); this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
this.currentModel = CameraMode.modePhoto; this.currentModel = CameraMode.modePhoto;
this.cameraModel.initCamera(this.surfaceId); //调用model/cameraModel.ts初始化相机功能 this.cameraModel.initCamera(this.surfaceId); //调用model/cameraModel.ts初始化相机功能
}) })
.width('100%') .width('100%')
.height('100%') .height('100%')
.margin({ bottom: 152 }) .margin({ bottom: 152 })
Column() { Column() {
} }
.width('97%') .width('97%')
.height('100%') .height('100%')
``` ```
3.初始化相机功能 3. 初始化相机功能
```typescript initCamera方法通过创建相机管理器实例cameraMgr来创建画面输出对象previewOutput。cameraMgr再通过创建CaptureSession实例来配置会话,完成相机功能的准备工作。
import image from '@ohos.multimedia.image';//自@ohos.multimedia.image引入image,提供图片处理效果
.................. ```typescript
private receiver: image.ImageReceiver = undefined;//图像接收类,用于获取组件surface id,接收最新的图片和读取下一张图片 import image from '@ohos.multimedia.image';//自@ohos.multimedia.image引入image,提供图片处理效果
.................. ...
constructor() { private receiver: image.ImageReceiver = undefined;//图像接收类,用于获取组件surface id,接收最新的图片和读取下一张图片
this.mediaModel = MediaModel.getMediaInstance();//通过调用model/MediaModel.ets中的方法创建mediaInstance类mediaModel ...
//创建ImageReceiver实例receiver constructor() {
this.receiver = image.createImageReceiver( this.mediaModel = MediaModel.getMediaInstance();//通过调用model/MediaModel.ets中的方法创建mediaInstance类mediaModel
cameraWH.width, //创建ImageReceiver实例receiver
cameraWH.height, this.receiver = image.createImageReceiver(
FOUR, cameraWH.width,
EIGHT cameraWH.height,
); FOUR,
//接收图片时注册回调 EIGHT
this.receiver.on('imageArrival', () => { );
//从ImageReceiver读取下一张图片 //接收图片时注册回调
this.receiver.readNextImage((err, image) => { this.receiver.on('imageArrival', () => {
if (err || image === undefined) { //从ImageReceiver读取下一张图片
return; this.receiver.readNextImage((err, image) => {
} if (err || image === undefined) {
//根据图像的组件类型从图像中获取组件缓存 return;
image.getComponent(FOUR, (errMsg, img) => { }
if (errMsg || img === undefined) { //根据图像的组件类型从图像中获取组件缓存
return; image.getComponent(FOUR, (errMsg, img) => {
} if (errMsg || img === undefined) {
let buffer = new ArrayBuffer(FOUR_THOUSAND_AND_SIXTY_NINE); return;
if (img.byteBuffer) { }
buffer = img.byteBuffer; let buffer = new ArrayBuffer(FOUR_THOUSAND_AND_SIXTY_NINE);
} if (img.byteBuffer) {
this.saveImage(buffer, image); buffer = img.byteBuffer;
}); }
}); this.saveImage(buffer, image);
}); });
} });
});
}
async initCamera(surfaceId: string): Promise<void> {
..................
try { async initCamera(surfaceId: string): Promise<void> {
this.cameraMgr = camera.getCameraManager(globalThis.cameraContext);//获取相机管理器实例 ...
} try {
this.camerasArray = this.cameraMgr.getSupportedCameras();//获取支持指定的相机设备对象 this.cameraMgr = camera.getCameraManager(globalThis.cameraContext);//获取相机管理器实例
if (this.camerasArray.length === 0) { }
return; this.camerasArray = this.cameraMgr.getSupportedCameras();//获取支持指定的相机设备对象
} if (this.camerasArray.length === 0) {
let mCamera = this.camerasArray[0]; return;
this.cameraInput = this.cameraMgr.createCameraInput(mCamera); }
this.cameraInput.open(); let mCamera = this.camerasArray[0];
this.capability = this.cameraMgr.getSupportedOutputCapability(mCamera);//查询相机设备支持的输出能力 this.cameraInput = this.cameraMgr.createCameraInput(mCamera);
let previewProfile = this.capability.previewProfiles[0]; this.cameraInput.open();
//通过相机管理器创建预览输出对象 this.capability = this.cameraMgr.getSupportedOutputCapability(mCamera);//查询相机设备支持的输出能力
this.previewOutput = this.cameraMgr.createPreviewOutput( let previewProfile = this.capability.previewProfiles[0];
previewProfile, //通过相机管理器创建预览输出对象
surfaceId //surfaceId从XComponent组件获取 this.previewOutput = this.cameraMgr.createPreviewOutput(
); previewProfile,
let rSurfaceId = await this.receiver.getReceivingSurfaceId();//获取一个surface id供其他组件使用 surfaceId //surfaceId从XComponent组件获取
let photoProfile = this.capability.photoProfiles[0]; );
//通过相机管理器创建照片输出对象 let rSurfaceId = await this.receiver.getReceivingSurfaceId();//获取一个surface id供其他组件使用
this.photoOutPut = this.cameraMgr.createPhotoOutput( let photoProfile = this.capability.photoProfiles[0];
photoProfile, //通过相机管理器创建照片输出对象
rSurfaceId //rSurfaceId通过构造函数中定义的图像接收类receiver获取 this.photoOutPut = this.cameraMgr.createPhotoOutput(
); photoProfile,
this.capSession = this.cameraMgr.createCaptureSession();//创建CaptureSession实例 rSurfaceId //rSurfaceId通过构造函数中定义的图像接收类receiver获取
this.capSession.beginConfig();//开始配置会话 );
this.capSession.addInput(this.cameraInput);//将cameraInput加入会话 this.capSession = this.cameraMgr.createCaptureSession();//创建CaptureSession实例
this.capSession.addOutput(this.previewOutput);//将预览输出加入会话 this.capSession.beginConfig();//开始配置会话
this.capSession.addOutput(this.photoOutPut);//将照片输出加入会话 this.capSession.addInput(this.cameraInput);//将cameraInput加入会话
await this.capSession.commitConfig();//提交配置信息 this.capSession.addOutput(this.previewOutput);//将预览输出加入会话
await this.capSession.start();//开始输出 this.capSession.addOutput(this.photoOutPut);//将照片输出加入会话
} await this.capSession.commitConfig();//提交配置信息
await this.capSession.start();//开始输出
``` }
4.点击按钮进行拍照 ```
```typescript 4. 点击按钮进行拍照
Image(this.getCameraIcon())
.size({ width: 64, height: 64 }) 拍照按钮通过Image组件呈现,其绑定的onClick方法调用takePicture方法开始拍照。
.margin({ left: 10 })
.id('camera') ```typescript
.onClick(() => { Image(this.getCameraIcon())
if (this.currentModel === CameraMode.modePhoto) { .size({ width: 64, height: 64 })
prompt.showToast({ message: '拍照中...', duration: 200 }); .margin({ left: 10 })
this.cameraModel.takePicture();//调用model/cameraModel.takePicture()开始拍照 .id('camera')
} .onClick(() => {
}) if (this.currentModel === CameraMode.modePhoto) {
``` prompt.showToast({ message: '拍照中...', duration: 200 });
this.cameraModel.takePicture();//调用model/cameraModel.takePicture()开始拍照
5.拍照功能具体实现 }
})
- 拍照 ```
```typescript 5. 拍照功能具体实现
async takePicture(): Promise<void> {
//设置拍照相关参数 - 拍照
let photoSettings = {
rotation: this.imageRotation, ```typescript
quality: camera.QualityLevel.QUALITY_LEVEL_MEDIUM, async takePicture(): Promise<void> {
location: { //设置拍照相关参数
// 位置信息,经纬度 let photoSettings = {
latitude: 12.9698, rotation: this.imageRotation,
longitude: 77.75, quality: camera.QualityLevel.QUALITY_LEVEL_MEDIUM,
altitude: 1000, location: {
}, // 位置信息,经纬度
mirror: false, latitude: 12.9698,
}; longitude: 77.75,
await this.photoOutPut.capture(photoSettings); altitude: 1000,
AppStorage.Set('isRefresh', true); },
} mirror: false,
``` };
await this.photoOutPut.capture(photoSettings);
- 保存图片 AppStorage.Set('isRefresh', true);
}
```typescript ```
..................//model/MediaModel.ts中定义的负责保存图片的相关方法
async createAndGetUri(mediaType: mediaLibrary.MediaType): Promise<mediaLibrary.FileAsset> { - 保存图片
let dateTimeUtil: DateTimeUtil = new DateTimeUtil();
let info: FileInfo = this.getInfoFromMediaType(mediaType); saveImage方法使用MediaModel中的createAndGetUri方法创建Image类型资源,将拍摄到的照片写入到这个资源中去。
let name: string = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`;//获取当前时间
let displayName: string = `${info.prefix}${name}${info.suffix}`; ```typescript
//获取公共目录路径。 //model/MediaModel.ts中定义的负责保存图片的相关方法
let publicPath: string = await this.mediaLibraryTest.getPublicDirectory( async createAndGetUri(mediaType: mediaLibrary.MediaType): Promise<mediaLibrary.FileAsset> {
info.directory let dateTimeUtil: DateTimeUtil = new DateTimeUtil();
);//通过引用自@ohos.multimedia.mediaLibrary的mediaLibraryTest类创建媒体资源,其中定义了媒体类型、名称、路径。 let info: FileInfo = this.getInfoFromMediaType(mediaType);
let fileAsset: mediaLibrary.FileAsset = await this.mediaLibraryTest.createAsset( let name: string = `${dateTimeUtil.getDate()}_${dateTimeUtil.getTime()}`;//获取当前时间
mediaType,//根据传入函数createAndGetUri的mediaType参数决定创建什么类型的媒体资源 let displayName: string = `${info.prefix}${name}${info.suffix}`;
displayName, //获取公共目录路径。
publicPath let publicPath: string = await this.mediaLibraryTest.getPublicDirectory(
); info.directory
return fileAsset; );//通过引用自@ohos.multimedia.mediaLibrary的mediaLibraryTest类创建媒体资源,其中定义了媒体类型、名称、路径。
} let fileAsset: mediaLibrary.FileAsset = await this.mediaLibraryTest.createAsset(
async getFdPath(fileAsset: mediaLibrary.FileAsset): Promise<number> { mediaType,//根据传入函数createAndGetUri的mediaType参数决定创建什么类型的媒体资源
let fd: number = await fileAsset.open('Rw');//打开当前文件 displayName,
return fd; publicPath
} );
.................. return fileAsset;
}
async saveImage(buffer: ArrayBuffer, img: image.Image): Promise<void> { async getFdPath(fileAsset: mediaLibrary.FileAsset): Promise<number> {
this.fileAsset = await this.mediaModel.createAndGetUri(mediaLibrary.MediaType.IMAGE); let fd: number = await fileAsset.open('Rw');//打开当前文件
//通过调用MediaModel中的方法创建Image类型资源 return fd;
this.photoPath = this.fileAsset.uri; }
this.fd = await this.mediaModel.getFdPath(this.fileAsset); ...
await fileIo.write(this.fd, buffer);//将拍摄的照片写入到Mediamodel传回的资源中去
await this.fileAsset.close(this.fd);//释放open函数 async saveImage(buffer: ArrayBuffer, img: image.Image): Promise<void> {
await img.release(); this.fileAsset = await this.mediaModel.createAndGetUri(mediaLibrary.MediaType.IMAGE);
if (this.takePictureHandle) { //通过调用MediaModel中的方法创建Image类型资源
this.takePictureHandle(this.photoPath); this.photoPath = this.fileAsset.uri;
} this.fd = await this.mediaModel.getFdPath(this.fileAsset);
} await fileIo.write(this.fd, buffer);//将拍摄的照片写入到Mediamodel传回的资源中去
``` await this.fileAsset.close(this.fd);//释放open函数
await img.release();
if (this.takePictureHandle) {
this.takePictureHandle(this.photoPath);
}
}
```
## 全部代码 ## 全部代码
...@@ -242,7 +250,8 @@ Image(this.getCameraIcon()) ...@@ -242,7 +250,8 @@ Image(this.getCameraIcon())
## 参考 ## 参考
[权限列表](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/permission-list.md#ohospermissiondistributed_datasync) - [权限列表](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/security/permission-list.md#ohospermissiondistributed_datasync)
- [@ohos.multimedia.camera](../application-dev/reference/apis/js-apis-camera.md)
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册