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

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

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


一、前言

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

  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 })
相关推荐
layman05281 小时前
webpack5 css-loader:从基础到原理
前端·css·webpack
半桔1 小时前
【前端小站】CSS 样式美学:从基础语法到界面精筑的实战宝典
前端·css·html
AI老李1 小时前
PostCSS完全指南:功能/配置/插件/SourceMap/AST/插件开发/自定义语法
前端·javascript·postcss
_OP_CHEN1 小时前
【前端开发之CSS】(一)初识 CSS:网页化妆术的终极指南,新手也能轻松拿捏页面美化!
前端·css·html·网页开发·样式表·界面美化
啊哈一半醒1 小时前
CSS 主流布局
前端·css·css布局·标准流 浮动 定位·flex grid 响应式布局
PHP武器库1 小时前
ULUI:不止于按钮和菜单,一个专注于“业务组件”的纯 CSS 框架
前端·css
电商API_180079052471 小时前
第三方淘宝商品详情 API 全维度调用指南:从技术对接到生产落地
java·大数据·前端·数据库·人工智能·网络爬虫
晓晓莺歌1 小时前
vue3某一个路由切换,导致所有路由页面均变成空白页
前端·vue.js
Up九五小庞2 小时前
开源埋点分析平台 ClkLog 本地部署 + Web JS 埋点测试实战--九五小庞
前端·javascript·开源
qq_177767373 小时前
React Native鸿蒙跨平台数据使用监控应用技术,通过setInterval每5秒更新一次数据使用情况和套餐使用情况,模拟了真实应用中的数据监控场景
开发语言·前端·javascript·react native·react.js·ecmascript·harmonyos