Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
Docs
提交
8f9059c7
D
Docs
项目概览
OpenHarmony
/
Docs
接近 2 年 前同步成功
通知
159
Star
292
Fork
28
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
D
Docs
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
8f9059c7
编写于
7月 14, 2023
作者:
W
wangqingkaihong
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
检视修改
Signed-off-by:
N
wangqingkaihong
<
wangqing@kaihong.com
>
上级
0196fee3
变更
4
展开全部
隐藏空白更改
内联
并排
Showing
4 changed file
with
1020 addition
and
955 deletion
+1020
-955
zh-cn/third-party-cases/distributed-canvas.md
zh-cn/third-party-cases/distributed-canvas.md
+365
-350
zh-cn/third-party-cases/distributed-file.md
zh-cn/third-party-cases/distributed-file.md
+432
-391
zh-cn/third-party-cases/figures/camerapreview.gif
zh-cn/third-party-cases/figures/camerapreview.gif
+0
-0
zh-cn/third-party-cases/take-picture-and-preview.md
zh-cn/third-party-cases/take-picture-and-preview.md
+223
-214
未找到文件。
zh-cn/third-party-cases/distributed-canvas.md
浏览文件 @
8f9059c7
此差异已折叠。
点击以展开。
zh-cn/third-party-cases/distributed-file.md
浏览文件 @
8f9059c7
此差异已折叠。
点击以展开。
zh-cn/third-party-cases/figures/camerapreview.gif
0 → 100644
浏览文件 @
8f9059c7
9.9 MB
zh-cn/third-party-cases/take-picture-and-preview.md
浏览文件 @
8f9059c7
...
@@ -8,10 +8,16 @@
...
@@ -8,10 +8,16 @@
本例效果如下:
本例效果如下:

| 拍照 | 预览 |
| :----------------------------------------------------------: | :----------------------------------------------------------: |
|
<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.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录