鸿蒙相机开发入门篇(官方实践版)

鸿蒙相机开发入门篇(官方实践版)

--- 从系统能力声明到可运行的拍照预览应用


一、前言

很多刚接触鸿蒙开发的同学,在尝试使用相机时会遇到两个常见问题:

  1. 为什么明明引入了相机模块,却提示"系统能力缺失"?
  2. 为什么写了相机逻辑,却看不到预览画面?

这篇文章将带你从 0 到 1 完成一个能"预览 + 拍照"的相机应用,完全基于 HarmonyOS NEXT 官方最佳实践,并结合 UI 层和交互讲解。


二、基础准备

1. 必要权限与系统能力声明

鸿蒙系统使用 SystemCapability(系统能力标识) 来声明模块功能。

在相机开发中,你必须在 module.json5 文件中声明以下内容:

json 复制代码
{
  "module": {
    "name": "entry",
    "requestPermissions": [
      { "name": "ohos.permission.CAMERA" },
      { "name": "ohos.permission.MICROPHONE" },
      { "name": "ohos.permission.WRITE_MEDIA" }
    ],
    "systemCapabilities": [
      "SystemCapability.Multimedia.Camera.Core",
      "SystemCapability.Multimedia.Camera.Basic",
      "SystemCapability.Multimedia.Camera.Metadata"
    ]
  }
}

⚠️ 注意:

鸿蒙要求编译时声明能力,否则构建期就会报错,这点和 Android 运行时动态声明完全不同。


三、创建相机基础结构

在鸿蒙中,Camera 模块的核心接口位于 @ohos.multimedia.camera

下面我们先构建一个基础拍照页面:

kotlin 复制代码
// pages/CameraPage.ets
import camera from '@ohos.multimedia.camera';
import media from '@ohos.multimedia.media';
import fileio from '@ohos.fileio';

@Entry
@Component
struct CameraPage {
  controller: camera.CameraManager = camera.getCameraManager(globalThis.context);
  previewOutput?: camera.PreviewOutput;
  photoOutput?: camera.PhotoOutput;
  cameraInput?: camera.CameraInput;

  build() {
    Column() {
      // 预览区域
      if (this.previewOutput) {
        // 使用 SurfaceId 渲染相机画面
        XComponent({ id: 'cameraView', type: XComponentType.SURFACE })
          .onLoad((context) => {
            this.startPreview(context);
          })
          .width('100%')
          .height('80%')
      }

      // 拍照按钮
      Button('拍照')
        .onClick(() => this.takePhoto())
        .width('50%')
        .height(50)
        .backgroundColor('#007DFF')
        .fontColor('#fff')
        .borderRadius(25)
    }
  }

  async startPreview(context) {
    const cameras = this.controller.getSupportedCameras();
    this.cameraInput = this.controller.createCameraInput(cameras[0]);
    this.previewOutput = this.controller.createPreviewOutput(context);
    this.photoOutput = this.controller.createPhotoOutput();

    const session = this.controller.createSession(camera.SessionType.SESSION_TYPE_NORMAL);
    await session.beginConfig();
    session.addInput(this.cameraInput);
    session.addOutput(this.previewOutput);
    session.addOutput(this.photoOutput);
    await session.commitConfig();
    session.start();

    await this.cameraInput.open();
    this.previewOutput.start();
  }

  async takePhoto() {
    if (!this.photoOutput) return;
    const photoPath = `/data/storage/el2/base/photos/${Date.now()}.jpg`;
    await this.photoOutput.capture(photoPath);
    prompt.showToast({ message: '拍照成功!', duration: 1500 });
  }
}

四、代码讲解

模块 说明
CameraManager 管理相机设备(前置/后置等)
CameraInput 表示相机输入(光学传感器)
PreviewOutput 负责输出实时预览帧(绑定 UI Surface)
PhotoOutput 负责拍照输出(生成 JPEG 文件)
Session 管理相机的输入输出会话,必须配置后才能启动

五、UI 层与交互优化

为了让拍照体验更自然,可以加入一个简洁的取景框样式与快门动效:

kotlin 复制代码
// 快门动画效果
@State shutterEffect: boolean = false

Button('拍照')
  .onClick(() => {
    this.shutterEffect = true
    setTimeout(() => (this.shutterEffect = false), 150)
    this.takePhoto()
  })
  .scale({ x: this.shutterEffect ? 0.9 : 1.0 })
  .animation({ duration: 150, curve: Curve.EaseInOut })
相关推荐
崔庆才丨静觅16 小时前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby606117 小时前
完成前端时间处理的另一块版图
前端·github·web components
掘了17 小时前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅17 小时前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅18 小时前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅18 小时前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment18 小时前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅18 小时前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊18 小时前
jwt介绍
前端
爱敲代码的小鱼18 小时前
AJAX(异步交互的技术来实现从服务端中获取数据):
前端·javascript·ajax