图片与多媒体开发:Image、Camera、音频播放
图片与多媒体开发:Image、Camera、音频播放
图片与音视频是富媒体应用的核心。鸿蒙在
@kit.ArkUI、@kit.CameraKit、@kit.MediaKit中提供完整能力。本文讲清图片加载/处理、相机调用、音频播放与录制,给出可运行示例与权限要点。
一、Image 图片加载
回顾 Image 的多种来源:
// 1. 本地资源
Image($r('app.media.logo')).width(80).height(80)
// 2. 网络图片(需 INTERNET 权限)
Image('https://example.com/p.jpg')
.width(200).height(200)
.objectFit(ImageFit.Cover)
.onComplete((msg) => { console.info('尺寸:' + msg.width + 'x' + msg.height); })
.onError(() => { console.error('加载失败'); })
// 3. 沙箱文件路径
Image('file://' + getContext(this).filesDir + '/local.png').width(100)
// 4. PixelMap(内存位图,可做圆角/模糊处理)
Image(this.pixelMap).width(100).height(100)
二、图片处理:圆角、裁剪、模糊
// 圆角
Image($r('app.media.avatar'))
.width(60).height(60)
.borderRadius(30) // 圆形头像
.clip(true)
// 模糊(背景虚化)
Image($r('app.media.bg'))
.blur(10) // 模糊半径
.width('100%').height(200)
// 缩放模式
Image(src)
.objectFit(ImageFit.Contain) // 完整显示不裁剪
圆形头像 = .borderRadius(宽高一半) + .clip(true),是社区最常用技巧。
三、图片选择器(用户选图)
调用系统图库选图,用 @kit.ImageKit 的 photoAccessHelper:
import { photoAccessHelper } from '@kit.ImageKit';
import { common } from '@kit.AbilityKit';
async function pickImage(context: common.UIAbilityContext): Promise<void> {
const picker = new photoAccessHelper.PhotoViewPicker();
const result = await picker.select({
MIMEType: photoAccessHelper.PhotoViewMimeType.IMAGE_TYPE,
maxSelectNumber: 1
});
const uri = result.photoUris[0];
console.info('选中图片:' + uri);
// 用 Image(uri) 直接显示,或复制到沙箱处理
}
选完拿到的是 URI,可直接给 Image() 显示,或复制到应用沙箱再做处理。
四、相机调用
拍照/录像需相机权限与 @kit.CameraKit:
// module.json5 权限
"requestPermissions": [
{ "name": "ohos.permission.CAMERA" },
{ "name": "ohos.permission.MICROPHONE" }
]
XComponent 承载相机预览,Camera Kit 控制采集。简化思路:
import { camera } from '@kit.CameraKit';
// 1) 获取相机管理器与相机输入
const cameraManager = camera.getCameraManager(context);
const cameras = cameraManager.getSupportedCameras();
const cameraInput = cameraManager.createCameraInput(cameras[0]);
// 2) 创建预览输出,绑定到 XComponent 的 surfaceId
const previewOutput = cameraManager.createPreviewOutput(profile, surfaceId);
// 3) 会话 start
const session = cameraManager.createCaptureSession();
session.addInput(cameraInput);
session.addOutput(previewOutput);
await session.start();
// 4) 拍照:创建 photoOutput,capture()
相机能力较强,真实项目建议封装成 CameraManager 单例,管理生命周期与权限弹窗。
五、音频播放
@kit.MediaKit 的 AVPlayer 播放音频/视频:
import { media } from '@kit.MediaKit';
async function playAudio(url: string): Promise<void> {
const player = await media.createAVPlayer();
player.url = url; // 网络或沙箱路径
player.on('stateChange', (state) => {
if (state === 'initialized') player.prepare();
if (state === 'prepared') player.play();
});
player.on('error', (err) => { console.error('播放错误:' + err); });
}
// 控制
// player.pause(); player.seek(10 * 1000); player.release();
状态机:idle → initialized → prepared → playing → paused → stopped。务必按状态流转调用,别在 initialized 就 play,否则报错。
六、音频录制
用 AVRecorder 录制:
import { media } from '@kit.MediaKit';
async function record(context: common.UIAbilityContext): Promise<void> {
const recorder = await media.createAVRecorder();
const avProfile: media.AVRecorderProfile = {
audioBitrate: 48000,
audioChannels: 1,
audioSampleRate: 48000,
audioCodec: media.CodecMimeType.AUDIO_AAC,
fileFormat: media.ContainerFormatType.CFT_MPEG_4A
};
const fd = fileIo.openSync(context.filesDir + '/rec.aac', 0o102, 0o666).fd;
await recorder.prepare(avProfile, fd);
await recorder.start();
// recorder.pause(); recorder.stop(); recorder.release();
}
录音需 MICROPHONE 权限。
七、视频播放
AVPlayer 同样支持视频,预览用 XComponent:
@Component
struct VideoPlayer {
private player?: media.AVPlayer;
private surfaceId: string = '';
build() {
Column() {
XComponent({ id: 'video', type: 'surface', controller: this.xc })
.onLoad((surfaceId) => { this.surfaceId = surfaceId; })
.width('100%').height(240)
Button('播放').onClick(() => { this.start(); })
}
}
async start(): Promise<void> {
this.player = await media.createAVPlayer();
this.player.url = 'https://example.com/a.mp4';
this.player.surfaceId = this.surfaceId; // 绑定渲染面
this.player.on('stateChange', (s) => { if (s === 'prepared') this.player!.play(); });
}
}
八、媒体库写入(保存图片/视频)
拍完的图要存进系统相册,用 photoAccessHelper 的 getAssets 写入:
async function saveToGallery(context: common.UIAbilityContext, fileUri: string): Promise<void> {
const ph = photoAccessHelper.getPhotoAccessHelper(context);
const asset = await ph.createAsset(photoAccessHelper.PhotoType.IMAGE, 'jpg');
// 用 asset 的 fd 把文件内容写入相册
}
九、权限最佳实践
媒体类权限大多需在 module.json5 声明,且敏感权限(相机、麦克风)运行时弹窗申请:
import { abilityAccessCtrl, PermissionRequestResult, common } from '@kit.AbilityKit';
async function reqCamera(context: common.UIAbilityContext): Promise<boolean> {
const atManager = abilityAccessCtrl.createAtManager();
const result: PermissionRequestResult = await atManager.requestPermissionsFromUser(
context, ['ohos.permission.CAMERA']
);
return result.authResults[0] === 0;
}
十、常见坑
| 现象 | 原因 | 解决 |
|---|---|---|
| 图片不显示 | 网络图未申 INTERNET | 加权限 |
| 相机黑屏 | surfaceId 未绑定 | XComponent onLoad 后设置 |
| 播放报错 | 状态未就绪就调用 | 按 stateChange 流转 |
| 录音频无声音 | 未申 MICROPHONE | 加权限并弹窗 |
十一、实战:头像上传
// 选图 → 显示 → 上传
@Component
struct AvatarUpload {
@State avatarUri: string = '';
build() {
Column() {
if (this.avatarUri !== '') {
Image(this.avatarUri).width(80).height(80).borderRadius(40).clip(true)
}
Button('选择头像').onClick(() => {
pickImage(getContext(this) as common.UIAbilityContext).then(uri => {
this.avatarUri = uri;
// 再调 api.post('/avatar', { file: uri })
});
})
}
}
}
十二、总结
鸿蒙的多媒体能力覆盖图片、相机、音视频全链路。Image 负责展示与处理(圆角/模糊/裁剪),photoAccessHelper 负责选图与存库,CameraKit 负责相机采集,MediaKit 的 AVPlayer/AVRecorder 负责播放与录制。核心三件事:权限先声明再申请、媒体对象按状态机流转、资源用完 release。掌握这些,你能做出带图、带声、带影像的富媒体应用。

更多推荐



所有评论(0)