鸿蒙相机开发中篇:自定义 UI 与拍摄控制

鸿蒙相机开发中篇:自定义 UI 与拍摄控制

------ 前后摄像头切换、点击对焦、曝光控制与动画动效


一、前言

上一篇《鸿蒙相机开发入门篇》中,我们完成了一个最小可用的相机应用,能实现预览与拍照。

但真正的相机 App 不只是能"拍",还要有流畅的交互体验,比如:

  • 自定义取景框
  • 切换前后摄像头
  • 点击自动对焦
  • 曝光补偿与预览动画

本篇将继续基于 @ohos.multimedia.camera 模块,带你逐步构建一个带交互控制与动效的相机 UI。


二、核心知识点回顾

功能 使用类 说明
前后摄像头切换 CameraManager.getSupportedCameras() 返回多个可用摄像头,通常索引 0 是后置,1 是前置
对焦控制 CameraInput.setFocusMode() / CameraInput.setFocusPoint() 设置自动/手动对焦点
曝光补偿 CameraInput.setExposureBias() 调节亮度
动画动效 ArkUI 动画系统 (.animation) 提供平滑的过渡和点击反馈

三、自定义取景框与 UI 布局

我们使用一个半透明取景框 + 工具栏布局:

typescript 复制代码
// pages/CustomCameraPage.ets
import camera from '@ohos.multimedia.camera';
import { prompt } from '@kit.ArkUI';

@Entry
@Component
struct CustomCameraPage {
  @State isFront: boolean = false;
  @State focusX: number = 0;
  @State focusY: number = 0;
  controller: camera.CameraManager = camera.getCameraManager(globalThis.context);
  session?: camera.Session;
  cameraInput?: camera.CameraInput;
  previewOutput?: camera.PreviewOutput;
  photoOutput?: camera.PhotoOutput;

  build() {
    Stack() {
      // 相机预览区域
      XComponent({ id: 'cameraPreview', type: XComponentType.SURFACE })
        .onLoad((context) => this.initCamera(context))
        .width('100%')
        .height('100%')
        .onTouch((event) => this.handleFocus(event)) // 点击对焦
      // 取景框遮罩
      Rect()
        .width('80%')
        .height('60%')
        .border({ width: 2, color: '#FFFFFF' })
        .opacity(0.5)
        .align(Alignment.Center)

      // 对焦点动画
      if (this.focusX !== 0) {
        Image($r('app.media.focus_ring'))
          .width(40)
          .height(40)
          .position({ x: this.focusX - 20, y: this.focusY - 20 })
          .animation({ duration: 300, curve: Curve.EaseOut })
      }

      // 底部工具栏
      Column({ space: 20 }) {
        Button(this.isFront ? '切换后摄' : '切换前摄')
          .onClick(() => this.switchCamera())
          .width(160).height(50)
          .backgroundColor('#444').fontColor('#fff').borderRadius(25)

        Button('拍照')
          .onClick(() => this.takePhoto())
          .width(100).height(100)
          .borderRadius(50)
          .backgroundColor('#007DFF')
      }
      .align(Alignment.BottomCenter)
      .padding(20)
    }
  }

四、前后摄像头切换逻辑

kotlin 复制代码
async initCamera(context) {
  const cameras = this.controller.getSupportedCameras();
  const selected = cameras[this.isFront ? 1 : 0];
  this.cameraInput = this.controller.createCameraInput(selected);
  this.previewOutput = this.controller.createPreviewOutput(context);
  this.photoOutput = this.controller.createPhotoOutput();

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

async switchCamera() {
  this.isFront = !this.isFront;
  await this.session?.stop();
  await this.cameraInput?.close();
  await this.initCamera(globalThis.context);
}

五、点击自动对焦

ini 复制代码
handleFocus(event) {
  const point = event.touches[0];
  this.focusX = point.x;
  this.focusY = point.y;

  if (this.cameraInput) {
    this.cameraInput.setFocusMode(camera.FocusMode.AUTO);
    this.cameraInput.setFocusPoint({ x: point.x, y: point.y });
  }

  setTimeout(() => {
    this.focusX = 0; // 动画结束隐藏
    this.focusY = 0;
  }, 800);
}

🔍 说明

  • setFocusMode() 可切换到自动或手动对焦。
  • 坐标点是基于 XComponent 的触摸事件。
  • 通过短暂显示对焦圆环动画反馈用户操作。

六、增加曝光调节

scss 复制代码
Slider({ value: 0, min: -1, max: 1, step: 0.1 })
  .onChange((value) => {
    if (this.cameraInput) {
      this.cameraInput.setExposureBias(value);
    }
  })
  .width('60%')
  .align(Alignment.BottomCenter)
  .margin({ bottom: 80 })

🌞 曝光值范围通常为 [-1, 1],可以根据光线场景动态调整。


七、小结与下一篇预告

到这里,我们已经实现了:

✅ 前后摄像头切换

✅ 点击自动对焦

✅ 曝光调节

✅ 自定义 UI 与对焦动效

下一篇(下篇:相机动效与性能优化)我们将继续探讨:

  • 相机启动/恢复动画
  • 快门和聚焦动效
  • 在 Worker 线程中使用相机(性能优化)
  • HDR、Vivid、高帧率预览
相关推荐
弓.长.17 小时前
ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-netinfo — 网络状态检测
网络·react native·harmonyos
弓.长.18 小时前
ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-network-info — 网络信息获取
网络·react native·harmonyos
弓.长.18 小时前
ReactNative for OpenHarmony项目鸿蒙化三方库:react-native-image-crop-picker — 图片选择裁剪组件
react native·react.js·harmonyos
讯方洋哥1 天前
HarmonyOS App开发——鸿蒙ArkTS基于首选项引导页的集成和应用
华为·harmonyos
左手厨刀右手茼蒿1 天前
Flutter 三方库 all_lint_rules_community 的鸿蒙化适配指南 - 在鸿蒙系统上构建极致、严谨、基于全量社区 Lint 规则的工业级静态代码质量与安全审计引擎
flutter·harmonyos·鸿蒙·openharmony·all_lint_rules_community
雷帝木木1 天前
Flutter for OpenHarmony:Flutter 三方库 cbor 构建 IoT 设备的极致压缩防窃协议(基于标准二进制 JSON 表达格式)
网络·物联网·flutter·http·json·harmonyos·鸿蒙
王码码20351 天前
Flutter 三方库 servicestack 的鸿蒙化适配指南 - 实现企业级 Message-based 架构集成、支持强类型 JSON 序列化与跨端服务调用同步
flutter·harmonyos·鸿蒙·openharmony·message-based
里欧跑得慢1 天前
Flutter 三方库 jsonata_dart 的鸿蒙化适配指南 - 实现高性能的 JSON 数据查询与转换、支持 JSONata 表达式引擎与端侧复杂数据清洗
flutter·harmonyos·鸿蒙·openharmony·jsonata_dart
chenyingjian2 天前
鸿蒙|性能优化-内存及其他优化
harmonyos
总有刁民想爱朕ha2 天前
haihong Os 鸿蒙开源版开发一个pc版软件应用(1)
华为·开源·harmonyos