鸿蒙6.1 camera坑:getCameraManager工厂非new+CameraPosition enum非字符串
本文是「鸿蒙 6.1 API 23 开发坑系列」第 14 篇(非 UI 系第 8 篇)。本篇讲
@ohos.multimedia.cameranamespace(API 10+,鸿蒙 6.1 API 23 基座)—— 相机管理camera.getCameraManager(context)工厂造CameraManager实例 +CameraManager.createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession工厂造CameraInput/PreviewOutput/PhotoOutput/CaptureSession实例 +CameraPosition/CameraType/CameraFormat/CameraStatusenum +CameraInput/PreviewOutput/PhotoOutput/CaptureSession/CameraDevice/CameraOutputCapability/Profile/CameraManagerinterface 不能 new。鸿蒙坑根因:①camera.getCameraManager(context: Context): CameraManager是工厂函数造CameraManager实例——CameraManager是 interface 不能new camera.CameraManager()(跟篇 7HttpRequestinterface 不能 new、篇 13ImageSourceinterface 不能 new 同理);②CameraManager.getSupportedCameras(): Array<CameraDevice>同步获取相机设备列表——CameraDevice是 interface 不能 new,含cameraId: string+cameraPosition: CameraPosition+cameraType: CameraType+connectionType: ConnectionType字段;③CameraPositionenum 常量CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2不是字符串'CAMERA_POSITION_BACK'(传字符串编译错,enum 值是数字 0/1/2 不是字符串);④CameraManager.createCameraInput(position: CameraPosition, type: CameraType): CameraInput工厂造CameraInput实例——CameraInput是 interface 不能 new,需先open()异步打开相机;⑤CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput工厂造PreviewOutput实例——surfaceId来自XComponent的getXComponentSurfaceId(),Profile用getSupportedOutputCapability().previewProfiles[0];⑥CameraManager.createCaptureSession(): CaptureSession工厂造CaptureSession实例——CaptureSession是 interface 不能 new,会话流程beginConfig()→addInput(cameraInput)→addOutput(previewOutput)→commitConfig()→start()。
一、开篇:鸿蒙 camera 不是浏览器 navigator.mediaDevices.getUserMedia,是「getCameraManager 工厂造 CameraManager」
你写 Web 前端时,相机预览用 navigator.mediaDevices.getUserMedia({ video: true })(返回 Promise<MediaStream>,<video> 元素 srcObject = stream 显示预览):
// Web:navigator.mediaDevices.getUserMedia 获取相机流
const stream: MediaStream = await navigator.mediaDevices.getUserMedia({
video: { facingMode: 'user' } // ✅ 前置摄像头('user')/ 后置摄像头('environment')
})
const video: HTMLVideoElement = document.querySelector('video')!
video.srcObject = stream // ✅ video.srcObject 显示预览
video.play()
你写鸿蒙 ArkTS 时,相机预览用 camera.getCameraManager(context) 工厂造 CameraManager 实例 + getSupportedCameras() 获取相机设备列表 + createCameraInput()/createPreviewOutput()/createCaptureSession() 工厂造 CameraInput/PreviewOutput/CaptureSession 实例:
// ArkTS camera.getCameraManager:工厂造 CameraManager(interface 不能 new)
import camera from '@ohos.multimedia.camera' // ✅ default import(camera 是 namespace)
import common from '@ohos.app.ability.common'
// ✅ getCameraManager 工厂造 CameraManager 实例(传 Context,interface 不能 new camera.CameraManager)
const cameraManager: camera.CameraManager = camera.getCameraManager(context as common.Context)
// ✅ getSupportedCameras 同步获取相机设备列表(CameraDevice[] 数组)
const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
console.info('相机数量: ' + cameras.length) // ✅ 通常 2 个(后置 + 前置)
// ✅ getSupportedOutputCapability 获取相机输出能力(previewProfiles/photoProfiles)
const capability: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameras[0])
const previewProfile: camera.Profile = capability.previewProfiles[0] // ✅ 预览 Profile
// 鸿蒙坑根因:getCameraManager 工厂造 CameraManager(interface 不能 new),CameraPosition enum 非字符串
Web vs 鸿蒙 camera 的区别:Web 把相机当 navigator.mediaDevices.getUserMedia({ video: { facingMode: 'user' } })(返回 Promise<MediaStream>,facingMode: 'user'/'environment' 字符串关键字选前后置),ArkTS 把相机当 camera.getCameraManager(context) 工厂造 CameraManager 实例 + getSupportedCameras() 获取相机设备列表(CameraDevice[] 数组,含 cameraPosition: CameraPosition enum 常量)+ createCameraInput()/createPreviewOutput()/createCaptureSession() 工厂造 CameraInput/PreviewOutput/CaptureSession 实例。根因不是 Promise 是工厂——鸿蒙 CameraManager 是 interface 不能 new camera.CameraManager()(用 camera.getCameraManager(context) 工厂造实例,context 必传),CameraInput/PreviewOutput/PhotoOutput/CaptureSession 都是 interface 不能 new(用 CameraManager.createCameraInput()/createPreviewOutput()/createPhotoOutput()/createCaptureSession() 工厂造实例),CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2 不是字符串 'CAMERA_POSITION_BACK'(传字符串触发 Type 'string' is not assignable to type 'CameraPosition' 编译错,enum 值是数字 0/1/2 不是字符串)。
二、根因:鸿蒙 @ohos.multimedia.camera 的六个绑定机制
鸿蒙 @ohos.multimedia.camera namespace(API 10+)核心导出 camera.getCameraManager(context) 工厂函数(造 CameraManager 实例)+ CameraManager interface(含 getSupportedCameras/getSupportedOutputCapability/createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession 方法)+ CameraInput/PreviewOutput/PhotoOutput/CaptureSession/CameraDevice/CameraOutputCapability/Profile/CameraStatus interface + CameraPosition/CameraType/CameraFormat/ConnectionType/SceneMode enum。绑定机制来自六重根因。
机制 1:camera.getCameraManager(context) 工厂造 CameraManager——CameraManager interface 不能 new
鸿蒙坑根因:camera.getCameraManager(context: Context): CameraManager 是工厂函数造 CameraManager 实例——CameraManager 是 interface 不能 new camera.CameraManager():
// ❌ 鸿蒙坑:CameraManager 是 interface 不能 new camera.CameraManager()
import camera from '@ohos.multimedia.camera'
import common from '@ohos.app.ability.common'
// ❌ new camera.CameraManager() 编译错(CameraManager 是 interface 不是 class,没有 constructor)
const manager1 = new camera.CameraManager() // ❌ 'CameraManager' only refers to a type
// ❌ new camera.CameraManager(context) 编译错(interface 没有 constructor 带参)
const manager2 = new camera.CameraManager(context as common.Context) // ❌ interface 不能 new
// ✅ 正确用法:camera.getCameraManager 工厂函数造 CameraManager 实例
const cameraManager: camera.CameraManager = camera.getCameraManager(context as common.Context) // ✅ 工厂造实例
// 鸿蒙坑根因:getCameraManager 工厂造 CameraManager(interface 不能 new,context 必传)
getCameraManager 工厂 CameraManager interface 不能 new 坑根因:鸿蒙 camera.getCameraManager(context: Context): CameraManager 是工厂函数造 CameraManager 实例(CameraManager 是 interface 不是 class,没有 constructor——new camera.CameraManager() 触发 'CameraManager' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑:context: Context 必传(context as common.Context 从 AbilityContext 转 Context),不传 context 编译错(Expected 1 arguments, but got 0)。React navigator.mediaDevices.getUserMedia() 不需要 context(浏览器全局 navigator 对象),鸿蒙 getCameraManager(context) 必传 context(Android-style Context 依赖注入,AbilityContext 提供 UIAbility 上下文)。CameraManager 是相机管理的总入口,所有相机操作(getSupportedCameras/getSupportedOutputCapability/createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession)都通过 CameraManager 实例调用。
机制 2:CameraManager.getSupportedCameras() 同步获取 CameraDevice[]——CameraDevice 是 interface
鸿蒙坑根因:CameraManager.getSupportedCameras(): Array<CameraDevice> 同步获取相机设备列表——CameraDevice 是 interface 不能 new,含 cameraId/cameraPosition/cameraType/connectionType 字段:
// ✅ 鸿蒙坑:getSupportedCameras 同步获取 CameraDevice[](CameraDevice 是 interface 不能 new)
import camera from '@ohos.multimedia.camera'
const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
console.info('相机数量: ' + cameras.length) // ✅ 通常 2 个(后置 + 前置)
// ✅ CameraDevice interface 字段(cameraId + cameraPosition + cameraType + connectionType)
cameras.forEach((cam: camera.CameraDevice, index: number) => {
console.info(`相机[${index}]: id=${cam.cameraId} position=${cam.cameraPosition} type=${cam.cameraType}`)
})
// ✅ 取后置相机(cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK)
const backCamera: camera.CameraDevice | undefined = cameras.find(
(cam: camera.CameraDevice) => cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK
)
if (!backCamera) {
console.error('没有后置相机')
return
}
// ✅ 取前置相机(cameraPosition === camera.CameraPosition.CAMERA_POSITION_FRONT)
const frontCamera: camera.CameraDevice | undefined = cameras.find(
(cam: camera.CameraDevice) => cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_FRONT
)
// 鸿蒙坑根因:getSupportedCameras 返回 CameraDevice[](interface 不能 new),cameraPosition 是 enum 不是字符串
getSupportedCameras + CameraDevice interface 坑根因:鸿蒙 CameraManager.getSupportedCameras(): Array<CameraDevice> 同步获取相机设备列表(不返回 Promise,直接返回数组),CameraDevice 是 interface 不能 new camera.CameraDevice()(用 getSupportedCameras() 工厂获取实例)。CameraDevice interface 含字段 cameraId: string(相机唯一标识)/cameraPosition: CameraPosition(相机位置 enum 常量)/cameraType: CameraType(相机类型 enum 常量)/connectionType: ConnectionType(连接类型 enum 常量,USB/WIRELESS 等)。鸿蒙坑:cameraPosition 是 CameraPosition enum 不是字符串(cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK enum 常量比较,❌ cam.cameraPosition === 'BACK' 字符串比较编译错)。React navigator.mediaDevices.getSupportedConstraints() 返回 MediaTrackSupportedConstraints 对象(含 facingMode: boolean 字段标识支持 facingMode),鸿蒙 getSupportedCameras() 返回 CameraDevice[] 数组(每个 CameraDevice 含 cameraPosition enum 标识前后置)。
机制 3:CameraPosition enum 常量 CAMERA_POSITION_BACK=0/FRONT=1 不是字符串’BACK’
鸿蒙坑根因:CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2 不是字符串 'CAMERA_POSITION_BACK'(传字符串编译错):
// ❌ 鸿蒙坑:CameraPosition enum 常量不是字符串'CAMERA_POSITION_BACK'
import camera from '@ohos.multimedia.camera'
// ❌ 传字符串'CAMERA_POSITION_BACK'编译错(CameraPosition 类型是 enum 不是 string)
const pos1: camera.CameraPosition = 'CAMERA_POSITION_BACK' // ❌ Type 'string' is not assignable to type 'CameraPosition'
// ❌ 传数字 0 编译错(enum 值是数字但类型必须 enum 常量不是 number)
const pos2: camera.CameraPosition = 0 // ❌ Type 'number' is not assignable to type 'CameraPosition'
// ❌ 传简写字符串'BACK'编译错(CameraPosition enum 没有'BACK'常量)
const pos3: camera.CameraPosition = 'BACK' // ❌ Type 'string' is not assignable to type 'CameraPosition'
// ✅ 正确用法:camera.CameraPosition.CAMERA_POSITION_BACK enum 常量(不是字符串,不是数字)
const pos4: camera.CameraPosition = camera.CameraPosition.CAMERA_POSITION_BACK // ✅ enum 常量 = 0
const pos5: camera.CameraPosition = camera.CameraPosition.CAMERA_POSITION_FRONT // ✅ enum 常量 = 1
const pos6: camera.CameraPosition = camera.CameraPosition.CAMERA_POSITION_UNSPECIFIED // ✅ enum 常量 = 2
// ✅ CameraPosition enum 常量语义:
// CAMERA_POSITION_BACK=0:后置相机(对应 React facingMode: 'environment')
// CAMERA_POSITION_FRONT=1:前置相机(对应 React facingMode: 'user')
// CAMERA_POSITION_UNSPECIFIED=2:未指定位置(通常外接 USB 相机)
// 鸿蒙坑根因:CameraPosition enum 常量 CAMERA_POSITION_BACK/FRONT/UNSPECIFIED 不是字符串 enum 值数字
CameraPosition enum 常量不是字符串坑根因:鸿蒙 CameraPosition enum 的三个常量是 CAMERA_POSITION_BACK=0(后置相机)/CAMERA_POSITION_FRONT=1(前置相机)/CAMERA_POSITION_UNSPECIFIED=2(未指定位置,通常外接 USB 相机)。鸿蒙坑:传字符串 'CAMERA_POSITION_BACK'/'BACK' 触发 Type 'string' is not assignable to type 'CameraPosition' 编译错——必须传 camera.CameraPosition.CAMERA_POSITION_BACK enum 常量(enum 值是数字 0 不是字符串)。传数字 0 也编译错(Type 'number' is not assignable to type 'CameraPosition',ArkTS 严格模式 enum 类型不接受裸数字)。React getUserMedia({ video: { facingMode: 'user' } }) 用字符串关键字 'user'/'environment' 选前后置(浏览器解析字符串),鸿蒙 camera.CameraPosition.CAMERA_POSITION_FRONT 用 enum 常量选前后置(编译期类型检查,enum 值是数字)。
机制 4:CameraManager.createCameraInput(position, type) 工厂造 CameraInput——CameraInput interface 不能 new
鸿蒙坑根因:CameraManager.createCameraInput(position: CameraPosition, type: CameraType): CameraInput 工厂造 CameraInput 实例——CameraInput 是 interface 不能 new,需先 open() 异步打开相机:
// ❌ 鸿蒙坑:CameraInput 是 interface 不能 new camera.CameraInput()
import camera from '@ohos.multimedia.camera'
// ❌ new camera.CameraInput() 编译错(CameraInput 是 interface 不是 class)
const input1 = new camera.CameraInput() // ❌ 'CameraInput' only refers to a type
// ✅ 正确用法:createCameraInput 工厂造 CameraInput 实例(两种重载)
// ✅ 重载 1:createCameraInput(camera: CameraDevice) 传 CameraDevice
const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
const backCamera: camera.CameraDevice = cameras[0] // ✅ 取后置相机
const cameraInput1: camera.CameraInput = cameraManager.createCameraInput(backCamera) // ✅ 传 CameraDevice
// ✅ 重载 2:createCameraInput(position: CameraPosition, type: CameraType) 传 enum 常量
const cameraInput2: camera.CameraInput = cameraManager.createCameraInput(
camera.CameraPosition.CAMERA_POSITION_BACK, // ✅ CameraPosition enum 常量不是字符串
camera.CameraType.CAMERA_TYPE_WIDE_ANGLE // ✅ CameraType enum 常量不是字符串
)
// ✅ CameraInput.open() 异步打开相机(返回 Promise<void>)
await cameraInput1.open() // ✅ 异步打开相机,必须 await
console.info('相机已打开')
// 鸿蒙坑根因:createCameraInput 工厂造 CameraInput(interface 不能 new),open() 异步打开相机
createCameraInput 工厂 CameraInput interface 不能 new 坑根因:鸿蒙 CameraManager.createCameraInput(camera: CameraDevice): CameraInput 或 createCameraInput(position: CameraPosition, type: CameraType): CameraInput 两种重载工厂函数造 CameraInput 实例(CameraInput 是 interface 不是 class,没有 constructor——new camera.CameraInput() 触发 'CameraInput' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑:CameraInput.open(): Promise<void> 异步打开相机(必须 await,不 await 后续操作会报错「相机未打开」),CameraInput.close(): Promise<void> 异步关闭相机(aboutToDisappear 生命周期调 close 释放资源),CameraInput.on('error', callback) 监听相机错误事件。React getUserMedia 打开相机直接返回 MediaStream(一步到位),鸿蒙 createCameraInput + open() 两步(先工厂造 CameraInput 实例,再 open 异步打开相机)。
机制 5:CameraManager.createPreviewOutput(profile, surfaceId) 工厂造 PreviewOutput——surfaceId 来自 XComponent
鸿蒙坑根因:CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂造 PreviewOutput 实例——surfaceId 来自 XComponent 的 getXComponentSurfaceId(),Profile 用 getSupportedOutputCapability().previewProfiles[0]:
// ❌ 鸿蒙坑:PreviewOutput 是 interface 不能 new camera.PreviewOutput()
import camera from '@ohos.multimedia.camera'
// ❌ new camera.PreviewOutput() 编译错(PreviewOutput 是 interface 不是 class)
const output1 = new camera.PreviewOutput() // ❌ 'PreviewOutput' only refers to a type
// ✅ 正确用法:createPreviewOutput 工厂造 PreviewOutput 实例(传 Profile + surfaceId)
// ✅ step 1:getSupportedOutputCapability 获取相机输出能力
const cameras: Array<camera.CameraDevice> = cameraManager.getSupportedCameras()
const capability: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameras[0])
const previewProfile: camera.Profile = capability.previewProfiles[0] // ✅ 取第一个预览 Profile
// ✅ step 2:XComponent 获取 surfaceId(预览渲染表面 ID)
// XComponent({ type: XComponentType.SURFACE, controller: this.xcomponentController })
// .onLoad(() => {
// const surfaceId: string = this.xcomponentController.getXComponentSurfaceId() // ✅ surfaceId 字符串
// this.startPreview(surfaceId, previewProfile)
// })
// ✅ step 3:createPreviewOutput 工厂造 PreviewOutput 实例
const previewOutput: camera.PreviewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId)
// 鸿蒙坑根因:createPreviewOutput 工厂造 PreviewOutput(interface 不能 new),surfaceId 来自 XComponent
createPreviewOutput 工厂 PreviewOutput interface 不能 new 坑根因:鸿蒙 CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂函数造 PreviewOutput 实例(PreviewOutput 是 interface 不是 class,没有 constructor——new camera.PreviewOutput() 触发 'PreviewOutput' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑:profile: Profile 必须用 getSupportedOutputCapability(cameras[0]).previewProfiles[0] 获取(不能手动构造 Profile 对象,Profile 是 interface 不能 new);surfaceId: string 必须来自 XComponent 的 getXComponentSurfaceId()(XComponent 是 ArkUI 的原生组件渲染表面,surfaceId 是底层 Surface 的唯一标识字符串)。React <video srcObject={stream}> 直接用 <video> 元素显示预览(浏览器渲染),鸿蒙 XComponent + PreviewOutput + surfaceId 三件套(XComponent 提供渲染表面,PreviewOutput 绑定 surfaceId 输出预览帧,底层 SurfaceFlinger 渲染)。
机制 6:CameraManager.createCaptureSession() 工厂造 CaptureSession——会话流程 beginConfig→addInput→addOutput→commitConfig→start
鸿蒙坑根因:CameraManager.createCaptureSession(): CaptureSession 工厂造 CaptureSession 实例——CaptureSession 是 interface 不能 new,会话流程 beginConfig() → addInput(cameraInput) → addOutput(previewOutput) → commitConfig() → start():
// ❌ 鸿蒙坑:CaptureSession 是 interface 不能 new camera.CaptureSession()
import camera from '@ohos.multimedia.camera'
// ❌ new camera.CaptureSession() 编译错(CaptureSession 是 interface 不是 class)
const session1 = new camera.CaptureSession() // ❌ 'CaptureSession' only refers to a type
// ✅ 正确用法:createCaptureSession 工厂造 CaptureSession 实例
const captureSession: camera.CaptureSession = cameraManager.createCaptureSession()
// ✅ 会话流程:beginConfig → addInput → addOutput → commitConfig → start
// ✅ step 1:beginConfig 开始配置会话
captureSession.beginConfig()
// ✅ step 2:addInput 添加 CameraInput(相机输入流)
await captureSession.addInput(cameraInput)
// ✅ step 3:addOutput 添加 PreviewOutput(预览输出流)
await captureSession.addOutput(previewOutput)
// ✅ step 4:commitConfig 提交配置(异步,返回 Promise<void>)
await captureSession.commitConfig()
// ✅ step 5:start 启动会话(异步,返回 Promise<void>,预览开始)
await captureSession.start()
console.info('相机预览已启动')
// ✅ step 6:stop 停止会话(aboutToDisappear 生命周期调)
await captureSession.stop()
// 鸿蒙坑根因:createCaptureSession 工厂造 CaptureSession(interface 不能 new),会话流程 5 步
createCaptureSession 工厂 CaptureSession interface 不能 new 坑根因:鸿蒙 CameraManager.createCaptureSession(): CaptureSession 工厂函数造 CaptureSession 实例(CaptureSession 是 interface 不是 class,没有 constructor——new camera.CaptureSession() 触发 'CaptureSession' only refers to a type, but is being used as a value here 编译错)。鸿蒙坑:CaptureSession 会话流程严格 5 步——beginConfig()(开始配置会话,同步方法)→ addInput(cameraInput)(添加 CameraInput 相机输入流,异步返回 Promise<void>)→ addOutput(previewOutput)(添加 PreviewOutput 预览输出流,异步返回 Promise<void>)→ commitConfig()(提交配置,异步返回 Promise<void>)→ start()(启动会话,异步返回 Promise<void>,预览开始)。鸿蒙坑:必须严格按 beginConfig → addInput → addOutput → commitConfig → start 顺序调用,颠倒顺序或跳步会报错(如 addInput 前 addOutput 报「会话未配置」错,commitConfig 后 addInput 报「会话已提交不能再配置」错)。React getUserMedia 直接返回 MediaStream(一步到位,无会话流程),鸿蒙 CaptureSession 会话流程 5 步(Android Camera2 API 风格,CaptureSession 对应 Android CameraCaptureSession,beginConfig/commitConfig 对应 Android SessionConfiguration)。
三、真机配图:鸿蒙 @ohos.multimedia.camera 相机坑——getCameraManager 工厂非 new + CameraPosition enum 非字符串

真机配图展示鸿蒙 @ohos.multimedia.camera 相机坑:
- camera 初始态:鸿蒙 6.1 @ohos.multimedia.camera 相机坑标题,5 个验证按钮(① getCameraManager 工厂非 new / ② CameraPosition enum 非字符串 / ③ createCameraInput 工厂非 new / ④ createPreviewOutput 工厂非 new / ⑤ createCaptureSession 会话流程 5 步),要点说明 7 条
- getCameraManager 工厂态:点击「① 验证 getCameraManager 工厂非 new」按钮,显示「✅ camera.getCameraManager(context) 工厂造 CameraManager 实例(interface 不能 new camera.CameraManager)」+ cameraManager 值——getCameraManager 工厂造 CameraManager(interface 不能 new)验证
- CameraPosition enum 态:点击「② 验证 CameraPosition enum 非字符串」按钮,显示「✅ CameraPosition enum 常量 CAMERA_POSITION_BACK=0 / CAMERA_POSITION_FRONT=1 / CAMERA_POSITION_UNSPECIFIED=2 不是字符串」+ cameras 数组——CameraPosition enum 常量非字符串验证
- createPreviewOutput 态:点击「④ 验证 createPreviewOutput 工厂非 new」按钮,显示「✅ createPreviewOutput(profile, surfaceId) 工厂造 PreviewOutput 实例(surfaceId 来自 XComponent)」+ previewOutput 值——createPreviewOutput 工厂造 PreviewOutput(surfaceId 来自 XComponent)验证
- CaptureSession 会话态:点击「⑤ 验证 createCaptureSession 会话流程 5 步」按钮,显示「✅ beginConfig → addInput → addOutput → commitConfig → start 会话流程 5 步」+ captureSession 值——CaptureSession 会话流程 5 步验证
四、真解法:鸿蒙 @ohos.multimedia.camera 的四个场景
场景 1:getCameraManager + getSupportedCameras + getSupportedOutputCapability 初始化相机
基础相机初始化用 camera.getCameraManager(context) 工厂造 CameraManager 实例 + getSupportedCameras() 获取相机设备列表 + getSupportedOutputCapability() 获取相机输出能力:
// ✅ 场景 1:getCameraManager + getSupportedCameras + getSupportedOutputCapability 初始化相机(API 10)
import camera from '@ohos.multimedia.camera' // ✅ default import(camera 是 namespace)
import common from '@ohos.app.ability.common'
@Entry
@Component
struct Index {
private cameraManager: camera.CameraManager | null = null
@State cameraInfo: string = '未初始化'
async initCamera(context: common.Context) {
// ✅ getCameraManager 工厂造 CameraManager 实例(interface 不能 new camera.CameraManager)
this.cameraManager = camera.getCameraManager(context)
if (!this.cameraManager) {
console.error('CameraManager 创建失败')
return
}
// ✅ getSupportedCameras 同步获取相机设备列表(CameraDevice[] 数组)
const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
if (cameras.length === 0) {
console.error('没有可用相机')
return
}
// ✅ getSupportedOutputCapability 获取相机输出能力(previewProfiles/photoProfiles)
const capability: camera.CameraOutputCapability = this.cameraManager.getSupportedOutputCapability(cameras[0])
const previewProfile: camera.Profile = capability.previewProfiles[0] // ✅ 预览 Profile
this.cameraInfo = `相机数量: ${cameras.length}\n` +
`后置相机: ${cameras.find(c => c.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK)?.cameraId ?? '无'}\n` +
`前置相机: ${cameras.find(c => c.cameraPosition === camera.CameraPosition.CAMERA_POSITION_FRONT)?.cameraId ?? '无'}`
}
build() {
Column({ space: 8 }) {
Button('初始化相机').onClick(() => this.initCamera(getContext(this) as common.Context))
Text(this.cameraInfo).fontSize(16).margin({ top: 20 })
}
}
}
// getCameraManager 工厂造 CameraManager(interface 不能 new)+ getSupportedCameras 获取 CameraDevice[]
鸿蒙 @ohos.multimedia.camera API 真名坑:import camera from '@ohos.multimedia.camera'(default import,camera 是 namespace);camera.getCameraManager(context: Context): CameraManager(工厂函数造 CameraManager 实例,context 必传从 AbilityContext 转 Context);CameraManager.getSupportedCameras(): Array<CameraDevice>(同步获取相机设备列表,CameraDevice interface 含 cameraId/cameraPosition/cameraType/connectionType 字段);CameraManager.getSupportedOutputCapability(camera: CameraDevice): CameraOutputCapability(同步获取相机输出能力,CameraOutputCapability interface 含 previewProfiles: Array<Profile>/photoProfiles: Array<Profile>/videoProfiles: Array<VideoProfile> 字段);CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2(不是字符串 'BACK',enum 值是数字);SysCap SystemCapability.Multimedia.Camera.Core / SystemCapability.Multimedia.Camera.Front / SystemCapability.Multimedia.Camera.Back;@atomicservice 原子化服务(API 11+)。
场景 2:createCameraInput + open 打开相机——CameraPosition/CameraType enum 常量
打开相机用 CameraManager.createCameraInput(position, type) 工厂造 CameraInput 实例 + CameraInput.open() 异步打开相机:
// ✅ 场景 2:createCameraInput + open 打开相机(API 10)
import camera from '@ohos.multimedia.camera'
@Entry
@Component
struct Index {
private cameraManager: camera.CameraManager | null = null
private cameraInput: camera.CameraInput | null = null
@State openStatus: string = '未打开'
async openCamera() {
if (!this.cameraManager) {
this.cameraManager = camera.getCameraManager(getContext(this) as common.Context)
}
// ✅ createCameraInput 工厂造 CameraInput 实例(两种重载)
// ✅ 重载 1:createCameraInput(camera: CameraDevice) 传 CameraDevice
const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
const backCamera: camera.CameraDevice = cameras.find(
(cam: camera.CameraDevice) => cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK
)!
this.cameraInput = this.cameraManager.createCameraInput(backCamera) // ✅ 传 CameraDevice
// ✅ 重载 2:createCameraInput(position: CameraPosition, type: CameraType) 传 enum 常量
// this.cameraInput = this.cameraManager.createCameraInput(
// camera.CameraPosition.CAMERA_POSITION_BACK, // ✅ CameraPosition enum 常量不是字符串
// camera.CameraType.CAMERA_TYPE_WIDE_ANGLE // ✅ CameraType enum 常量不是字符串
// )
// ✅ CameraInput.open() 异步打开相机(返回 Promise<void>,必须 await)
await this.cameraInput.open()
this.openStatus = '相机已打开'
console.info('相机已打开')
// ✅ CameraInput.on('error', callback) 监听相机错误事件
this.cameraInput.on('error', (error: camera.CameraInputErrorCode) => {
console.error('相机错误: ' + error)
})
}
build() {
Column({ space: 8 }) {
Button('打开相机').onClick(() => this.openCamera())
Text(this.openStatus).fontSize(16).margin({ top: 20 })
}
}
}
// createCameraInput 工厂造 CameraInput(interface 不能 new)+ open() 异步打开相机
鸿蒙 createCameraInput + open API 真名坑:CameraManager.createCameraInput(camera: CameraDevice): CameraInput 或 createCameraInput(position: CameraPosition, type: CameraType): CameraInput 两种重载工厂函数造 CameraInput 实例(CameraInput 是 interface 不能 new);CameraPosition enum 常量 CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2(不是字符串 'BACK',enum 值是数字);CameraType enum 常量 CAMERA_TYPE_WIDE_ANGLE=0(广角)/CAMERA_TYPE_TELEPHOTO=1(长焦)/CAMERA_TYPE_ULTRA_WIDE=2(超广角)/CAMERA_TYPE_DEFAULT=3(默认)(不是字符串 'WIDE_ANGLE',enum 值是数字);CameraInput.open(): Promise<void> 异步打开相机(必须 await);CameraInput.close(): Promise<void> 异步关闭相机(aboutToDisappear 生命周期调 close 释放资源);CameraInput.on('error', callback: (error: camera.CameraInputErrorCode) => void) 监听相机错误事件;React getUserMedia({ video: { facingMode: 'user' } }) 用字符串关键字 'user'/'environment' 选前后置(浏览器解析字符串),鸿蒙 CameraPosition enum 常量选前后置(编译期类型检查,enum 值是数字)。
场景 3:createPreviewOutput + XComponent 预览相机流——surfaceId 来自 XComponent
预览相机流用 CameraManager.createPreviewOutput(profile, surfaceId) 工厂造 PreviewOutput 实例 + XComponent 获取 surfaceId:
// ✅ 场景 3:createPreviewOutput + XComponent 预览相机流(API 10)
import camera from '@ohos.multimedia.camera'
import common from '@ohos.app.ability.common'
import { XComponent, XComponentType } from '@kit.ArkUI'
@Entry
@Component
struct Index {
private cameraManager: camera.CameraManager | null = null
private cameraInput: camera.CameraInput | null = null
private previewOutput: camera.PreviewOutput | null = null
private captureSession: camera.CaptureSession | null = null
private xcomponentController: XComponentController = new XComponentController()
@State previewStarted: boolean = false
async startPreview(surfaceId: string, previewProfile: camera.Profile) {
// ✅ createCameraInput 工厂造 CameraInput 实例
const cameras: Array<camera.CameraDevice> = this.cameraManager!.getSupportedCameras()
this.cameraInput = this.cameraManager!.createCameraInput(cameras[0])
await this.cameraInput.open() // ✅ 异步打开相机
// ✅ createPreviewOutput 工厂造 PreviewOutput 实例(传 Profile + surfaceId)
this.previewOutput = this.cameraManager!.createPreviewOutput(previewProfile, surfaceId)
// ✅ createCaptureSession 工厂造 CaptureSession 实例
this.captureSession = this.cameraManager!.createCaptureSession()
// ✅ 会话流程 5 步:beginConfig → addInput → addOutput → commitConfig → start
this.captureSession.beginConfig()
await this.captureSession.addInput(this.cameraInput)
await this.captureSession.addOutput(this.previewOutput)
await this.captureSession.commitConfig()
await this.captureSession.start() // ✅ 启动预览
this.previewStarted = true
}
build() {
Column({ space: 8 }) {
// ✅ XComponent 提供渲染表面,onLoad 回调获取 surfaceId
XComponent({ type: XComponentType.SURFACE, controller: this.xcomponentController })
.onLoad(() => {
// ✅ getXComponentSurfaceId 获取 surfaceId(字符串,来自底层 Surface)
const surfaceId: string = this.xcomponentController.getXComponentSurfaceId()
// ✅ 初始化相机管理器
this.cameraManager = camera.getCameraManager(getContext(this) as common.Context)
// ✅ 获取预览 Profile
const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
const capability: camera.CameraOutputCapability =
this.cameraManager.getSupportedOutputCapability(cameras[0])
const previewProfile: camera.Profile = capability.previewProfiles[0]
// ✅ 启动预览
this.startPreview(surfaceId, previewProfile)
})
.width('100%').height(400)
Text(this.previewStarted ? '预览已启动' : '预览启动中...').fontSize(16)
}
}
}
// createPreviewOutput 工厂造 PreviewOutput(interface 不能 new)+ XComponent surfaceId
鸿蒙 createPreviewOutput + XComponent API 真名坑:CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput 工厂函数造 PreviewOutput 实例(PreviewOutput 是 interface 不能 new);profile: Profile 必须用 getSupportedOutputCapability(cameras[0]).previewProfiles[0] 获取(Profile 是 interface 不能 new,含 width: number/height: number/format: CameraFormat 字段);surfaceId: string 必须来自 XComponent 的 getXComponentSurfaceId()(XComponent 是 ArkUI 原生组件渲染表面,surfaceId 是底层 Surface 的唯一标识字符串);CameraFormat enum 常量 CAMERA_FORMAT_RGBA_8888=3/CAMERA_FORMAT_YUV_420_SP=1003/CAMERA_FORMAT_JPEG=2000(不是字符串 'RGBA_8888',enum 值是数字);React <video srcObject={stream}> 直接用 <video> 元素显示预览(浏览器渲染),鸿蒙 XComponent + PreviewOutput + surfaceId 三件套(XComponent 提供渲染表面,PreviewOutput 绑定 surfaceId 输出预览帧,底层 SurfaceFlinger 渲染)。
场景 4:createCaptureSession 会话流程 5 步——beginConfig→addInput→addOutput→commitConfig→start
会话流程用 CameraManager.createCaptureSession() 工厂造 CaptureSession 实例 + 5 步会话流程 beginConfig → addInput → addOutput → commitConfig → start:
// ✅ 场景 4:createCaptureSession 会话流程 5 步(API 10)
import camera from '@ohos.multimedia.camera'
@Entry
@Component
struct Index {
private cameraManager: camera.CameraManager | null = null
private cameraInput: camera.CameraInput | null = null
private previewOutput: camera.PreviewOutput | null = null
private captureSession: camera.CaptureSession | null = null
async startSession() {
if (!this.cameraManager) {
this.cameraManager = camera.getCameraManager(getContext(this) as common.Context)
}
// ✅ step 1:createCameraInput 工厂造 CameraInput 实例 + open 异步打开相机
const cameras: Array<camera.CameraDevice> = this.cameraManager.getSupportedCameras()
this.cameraInput = this.cameraManager.createCameraInput(cameras[0])
await this.cameraInput.open() // ✅ 异步打开相机
// ✅ step 2:createPreviewOutput 工厂造 PreviewOutput 实例(surfaceId 从 XComponent 获取)
const capability: camera.CameraOutputCapability =
this.cameraManager.getSupportedOutputCapability(cameras[0])
const previewProfile: camera.Profile = capability.previewProfiles[0]
// const surfaceId: string = this.xcomponentController.getXComponentSurfaceId()
this.previewOutput = this.cameraManager.createPreviewOutput(previewProfile, surfaceId)
// ✅ step 3:createCaptureSession 工厂造 CaptureSession 实例(interface 不能 new)
this.captureSession = this.cameraManager.createCaptureSession()
// ✅ 会话流程 5 步(严格按顺序调用)
// ✅ step 3a:beginConfig 开始配置会话(同步方法)
this.captureSession.beginConfig()
// ✅ step 3b:addInput 添加 CameraInput(相机输入流,异步返回 Promise<void>)
await this.captureSession.addInput(this.cameraInput)
// ✅ step 3c:addOutput 添加 PreviewOutput(预览输出流,异步返回 Promise<void>)
await this.captureSession.addOutput(this.previewOutput)
// ✅ step 3d:commitConfig 提交配置(异步返回 Promise<void>)
await this.captureSession.commitConfig()
// ✅ step 3e:start 启动会话(异步返回 Promise<void>,预览开始)
await this.captureSession.start()
console.info('相机预览已启动')
}
// ✅ aboutToDisappear 生命周期释放资源(避免内存泄漏)
async aboutToDisappear() {
if (this.captureSession) {
await this.captureSession.stop() // ✅ stop 停止会话
}
if (this.cameraInput) {
await this.cameraInput.close() // ✅ close 关闭相机
}
if (this.previewOutput) {
await this.previewOutput.release() // ✅ release 释放 PreviewOutput
}
if (this.captureSession) {
await this.captureSession.release() // ✅ release 释放 CaptureSession
}
}
build() {
Column({ space: 8 }) {
Button('启动会话').onClick(() => this.startSession())
}
}
}
// createCaptureSession 工厂造 CaptureSession(interface 不能 new)+ 会话流程 5 步
鸿蒙 createCaptureSession 会话流程 5 步 API 真名坑:CameraManager.createCaptureSession(): CaptureSession 工厂函数造 CaptureSession 实例(CaptureSession 是 interface 不能 new);会话流程严格 5 步——beginConfig()(开始配置会话,同步方法,无返回值)→ addInput(cameraInput: CameraInput): Promise<void>(添加 CameraInput 相机输入流,异步)→ addOutput(previewOutput: PreviewOutput): Promise<void>(添加 PreviewOutput 预览输出流,异步)→ commitConfig(): Promise<void>(提交配置,异步)→ start(): Promise<void>(启动会话,异步,预览开始);鸿蒙坑:必须严格按 beginConfig → addInput → addOutput → commitConfig → start 顺序调用,颠倒顺序或跳步会报错(如 addInput 前 addOutput 报「会话未配置」错,commitConfig 后 addInput 报「会话已提交不能再配置」错);CaptureSession.stop(): Promise<void> 停止会话(aboutToDisappear 生命周期调);CaptureSession.release(): Promise<void> 释放会话资源(避免内存泄漏);aboutToDisappear 生命周期必须调 stop() + close() + release() 释放资源(相机硬件资源不释放会导致后续应用无法使用相机);React getUserMedia 直接返回 MediaStream(一步到位,无会话流程),鸿蒙 CaptureSession 会话流程 5 步(Android Camera2 API 风格,CaptureSession 对应 Android CameraCaptureSession,beginConfig/commitConfig 对应 Android SessionConfiguration)。
五、一句话哲学
写鸿蒙 ArkTS 记住:camera 不是浏览器 navigator.mediaDevices.getUserMedia 是「getCameraManager 工厂造 CameraManager」——鸿蒙 6.1 API 23
@ohos.multimedia.cameranamespace(API 10+,鸿蒙 6.1 API 23 基座,camera.getCameraManager(context)工厂造CameraManager实例 +CameraManager.createCameraInput/createPreviewOutput/createPhotoOutput/createCaptureSession工厂造CameraInput/PreviewOutput/PhotoOutput/CaptureSession实例 +CameraPosition/CameraType/CameraFormat/CameraStatus/ConnectionType/SceneModeenum +CameraInput/PreviewOutput/PhotoOutput/CaptureSession/CameraDevice/CameraOutputCapability/Profile/CameraManagerinterface 不能 new +InitializationOptions/DecodingOptions/ImageInfo/Size/Region类型,SysCap SystemCapability.Multimedia.Camera.Core / SystemCapability.Multimedia.Camera.Front / SystemCapability.Multimedia.Camera.Back,@atomicservice)。根因不是 Promise 是工厂——camera.getCameraManager(context: Context): CameraManager工厂函数造CameraManager实例(✅const cameraManager: camera.CameraManager = camera.getCameraManager(context as common.Context)工厂造实例,❌new camera.CameraManager()触发'CameraManager' only refers to a type, but is being used as a value here编译错,CameraManager是 interface 不是 class 没有 constructor,context: Context必传从AbilityContext转Context,不传 context 编译错Expected 1 arguments, but got 0,跟篇 7HttpRequestinterface 不能 new 用http.createHttp()工厂造实例、篇 13ImageSourceinterface 不能 new 用image.createImageSource()工厂造实例同理,Reactnavigator.mediaDevices.getUserMedia()不需要 context 浏览器全局navigator对象差异,鸿蒙getCameraManager(context)必传 context Android-style Context 依赖注入 AbilityContext 提供 UIAbility 上下文),CameraManager.getSupportedCameras(): Array<CameraDevice>同步获取相机设备列表(不返回 Promise 直接返回数组,CameraDevice是 interface 不能new camera.CameraDevice()用getSupportedCameras()工厂获取实例,含cameraId: string/cameraPosition: CameraPosition/cameraType: CameraType/connectionType: ConnectionType字段,cameraPosition是CameraPositionenum 不是字符串cam.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACKenum 常量比较 ❌cam.cameraPosition === 'BACK'字符串比较编译错),CameraPositionenum 常量CAMERA_POSITION_BACK=0/CAMERA_POSITION_FRONT=1/CAMERA_POSITION_UNSPECIFIED=2不是字符串'CAMERA_POSITION_BACK'(❌'CAMERA_POSITION_BACK'触发Type 'string' is not assignable to type 'CameraPosition'编译错,❌0触发Type 'number' is not assignable to type 'CameraPosition'编译错 ArkTS 严格模式 enum 类型不接受裸数字,✅camera.CameraPosition.CAMERA_POSITION_BACKenum 常量 enum 值是数字 0/1/2 不是字符串,对应 ReactgetUserMedia({ video: { facingMode: 'user' } })字符串关键字'user'/'environment'选前后置浏览器解析字符串差异,鸿蒙CameraPositionenum 常量选前后置编译期类型检查 enum 值是数字),CameraManager.createCameraInput(camera: CameraDevice): CameraInput或createCameraInput(position: CameraPosition, type: CameraType): CameraInput两种重载工厂函数造CameraInput实例(CameraInput是 interface 不能new camera.CameraInput()触发'CameraInput' only refers to a type, but is being used as a value here编译错,CameraInput.open(): Promise<void>异步打开相机必须 await 不 await 后续操作会报错「相机未打开」,CameraInput.close(): Promise<void>异步关闭相机aboutToDisappear生命周期调 close 释放资源,CameraInput.on('error', callback: (error: camera.CameraInputErrorCode) => void)监听相机错误事件,CameraTypeenum 常量CAMERA_TYPE_WIDE_ANGLE=0/CAMERA_TYPE_TELEPHOTO=1/CAMERA_TYPE_ULTRA_WIDE=2/CAMERA_TYPE_DEFAULT=3不是字符串'WIDE_ANGLE'enum 值是数字,ReactgetUserMedia打开相机直接返回MediaStream一步到位差异,鸿蒙createCameraInput+open()两步先工厂造 CameraInput 实例再 open 异步打开相机),CameraManager.createPreviewOutput(profile: Profile, surfaceId: string): PreviewOutput工厂函数造PreviewOutput实例(PreviewOutput是 interface 不能new camera.PreviewOutput()触发'PreviewOutput' only refers to a type, but is being used as a value here编译错,profile: Profile必须用getSupportedOutputCapability(cameras[0]).previewProfiles[0]获取不能手动构造Profile对象Profile是 interface 不能 new 含width: number/height: number/format: CameraFormat字段,surfaceId: string必须来自XComponent的getXComponentSurfaceId()XComponent是 ArkUI 原生组件渲染表面surfaceId是底层 Surface 的唯一标识字符串,CameraFormatenum 常量CAMERA_FORMAT_RGBA_8888=3/CAMERA_FORMAT_YUV_420_SP=1003/CAMERA_FORMAT_JPEG=2000不是字符串'RGBA_8888'enum 值是数字,React<video srcObject={stream}>直接用<video>元素显示预览浏览器渲染差异,鸿蒙XComponent+PreviewOutput+surfaceId三件套XComponent提供渲染表面PreviewOutput绑定 surfaceId 输出预览帧底层 SurfaceFlinger 渲染),CameraManager.createCaptureSession(): CaptureSession工厂函数造CaptureSession实例(CaptureSession是 interface 不能new camera.CaptureSession()触发'CaptureSession' only refers to a type, but is being used as a value here编译错,会话流程严格 5 步——beginConfig()开始配置会话同步方法无返回值 →addInput(cameraInput: CameraInput): Promise<void>添加 CameraInput 相机输入流异步 →addOutput(previewOutput: PreviewOutput): Promise<void>添加 PreviewOutput 预览输出流异步 →commitConfig(): Promise<void>提交配置异步 →start(): Promise<void>启动会话异步预览开始,必须严格按beginConfig→addInput→addOutput→commitConfig→start顺序调用颠倒顺序或跳步会报错如addInput前addOutput报「会话未配置」错commitConfig后addInput报「会话已提交不能再配置」错,CaptureSession.stop(): Promise<void>停止会话aboutToDisappear生命周期调,CaptureSession.release(): Promise<void>释放会话资源避免内存泄漏,aboutToDisappear生命周期必须调stop()+close()+release()释放资源相机硬件资源不释放会导致后续应用无法使用相机,ReactgetUserMedia直接返回MediaStream一步到位无会话流程差异,鸿蒙CaptureSession会话流程 5 步 Android Camera2 API 风格CaptureSession对应 AndroidCameraCaptureSessionbeginConfig/commitConfig对应 AndroidSessionConfiguration)。getCameraManager 工厂造 CameraManager(interface 不能 new,context 必传)+ getSupportedCameras 同步获取 CameraDevice[](CameraDevice 是 interface 不能 new)+ CameraPosition enum 常量 CAMERA_POSITION_BACK=0/FRONT=1/UNSPECIFIED=2 不是字符串 enum 值数字 + createCameraInput 工厂造 CameraInput(interface 不能 new)+ open() 异步打开相机 + CameraType enum 常量 CAMERA_TYPE_WIDE_ANGLE=0/TELEPHOTO=1/ULTRA_WIDE=2/DEFAULT=3 不是字符串 + createPreviewOutput 工厂造 PreviewOutput(interface 不能 new)+ surfaceId 来自 XComponent + Profile 用 getSupportedOutputCapability().previewProfiles[0] + CameraFormat enum 常量 CAMERA_FORMAT_RGBA_8888=3/YUV_420_SP=1003/JPEG=2000 不是字符串 + createCaptureSession 工厂造 CaptureSession(interface 不能 new)+ 会话流程 5 步 beginConfig→addInput→addOutput→commitConfig→start 严格顺序 + aboutToDisappear 生命周期 stop+close+release 释放资源 是鸿蒙 6.1 @ohos.multimedia.camera 相机坑核心!
能力系列回链
- 鸿蒙 7.0 新特性篇 1~17(沉浸式毛玻璃/Component3D/智能体框架/方舟引擎/星盾安全/星河互联/空间音频/可变字体/游戏快启/分布式数据盾/LTPO 可变帧率/AI 文档识别/多形态服务窗口/AI 反诈/机密计算/空间计算/小艺全面进化)
- 鸿蒙 6.1 API 23 开发坑系列篇 1「ArkUI.modifier 装饰器坑」——attributeModifier + AttributeModifier 状态化节点修改器
- 鸿蒙 6.1 API 23 开发坑系列篇 2「arkui.componentSnapshot 组件截图坑」——get/getSync/createFromBuilder 返回 image.PixelMap 像素图
- 鸿蒙 6.1 API 23 开发坑系列篇 3「arkui.node 节点坑」——NodeController abstract class makeNode override + BuilderNode WrappedBuilder
- 鸿蒙 6.1 API 23 开发坑系列篇 4「arkui.UIContext UI 上下文坑」——runScopedTask 不是 runScopedOnUiThread + 11 个子管理器
- 鸿蒙 6.1 API 23 开发坑系列篇 5「arkui.observer UI 观察器坑」——uiObserver namespace 真名不是 observer + on type string literal
- 鸿蒙 6.1 API 23 开发坑系列篇 6「@ohos.animator 动画器坑」——import @kit.ArkUI 不是 @ohos.animator + onFrame 驼峰不是废弃 onframe + getUIContext().createAnimator 不是废弃 animator.create + 持引用 + aboutToDisappear cancel
- 鸿蒙 6.1 API 23 开发坑系列篇 7「@ohos.net.http HTTP 请求坑」——HttpDataType 常量是 STRING 不是 STRING_TYPE + HttpRequest 是 interface 不能 new + http.createHttp() 工厂造实例 + on/off 监听不是 addEventListener + header Record 不是 Headers + RequestMethod enum 不是字符串
- 鸿蒙 6.1 API 23 开发坑系列篇 8「@ohos.file.fs 文件管理坑」——writeSync/readSync 是 namespace 顶层函数不是 File 实例方法 + 第一参传 file.fd 文件描述符 + ReadOptions 无 encoding 读 ArrayBuffer 原字节 + WriteOptions 带 encoding 写字符串指定编码 + closeSync(file) 传 File 不是 fd + OpenMode enum 不是 flags 数字
- 鸿蒙 6.1 API 23 开发坑系列篇 9「@ohos.router 页面路由坑」——router.push/replace 废弃迁移 pushUrl/replaceUrl + RouterMode enum 常量 Standard/Single 不是字符串 + RouterOptions.url 绝对路径不是相对路径 + getParams 返回 Object 要 as Record 转型 + RouterState 真属性 index/name 不是 stackLength + getLength 返回 string 不是 number
- 鸿蒙 6.1 API 23 开发坑系列篇 10「@ohos.promptAction 弹窗坑」——showToast/showDialog/showActionMenu 废弃迁移 getPromptAction + ToastType enum 常量 Default/Bottom/Center/Top 不是字符串 + ShowToastOptions.duration 单位 10ms 不是 1ms + showDialog 回调 onAccept/onCancel 不是 onConfirm/onAbort + DialogButton.action 不是 onClick 无 bgColor + showActionMenu buttons 上限 6 不是无限
- 鸿蒙 6.1 API 23 开发坑系列篇 11「@ohos.measure 文本测量坑」——measureText 返回 number 不是 TextMetrics + measureTextSize 返回 SizeOptions 多行测量 + MeasureOptions 必填 textContent 不是 text + fontSize string 须带 fp/px 单位 + MeasureText static 废弃迁移 getMeasureUtils 实例方法
- 鸿蒙 6.1 API 23 开发坑系列篇 12「@ohos.curves 动画曲线坑」——init/cubicBezier/spring/steps 废弃返回 string 迁移 initCurve 等返回 ICurve + ICurve interface 不能 new 用工厂函数造实例 + Curve enum 常量 Linear/Ease 等不是字符串 enum 值数字 + cubicBezierCurve 四 number 不是 cubic-bezier 字符串 + springCurve 四 number damping 越大震动越小 + customCurve 回调 fraction [0,1] 返回必须 [0,1]
- 鸿蒙 6.1 API 23 开发坑系列篇 13「@ohos.multimedia.image 图片处理坑」——createImageSource 工厂造 ImageSource(interface 不能 new)+ PixelMapFormat enum 常量 ALPHA_8/RGB_565/RGBA_8888/ARGB_8888/RGB_888 不是字符串 + createPixelMap 创建空 PixelMap InitializationOptions 三必填 size+pixelFormat+editable + ImageSource.createPixelMap 带 DecodingOptions 解码指定尺寸/区域/旋转 + PixelMap.readPixelsToBuffer 读像素到 ArrayBuffer(不是 getImageData 返回 ImageData)+ createIncrementalSource + updateData 流式解码大图避免 OOM
- 鸿蒙 6.1 API 23 开发坑系列篇 14「@ohos.multimedia.camera 相机坑」——getCameraManager 工厂造 CameraManager(interface 不能 new,context 必传)+ getSupportedCameras 同步获取 CameraDevice[](CameraDevice 是 interface 不能 new)+ CameraPosition enum 常量 CAMERA_POSITION_BACK=0/FRONT=1/UNSPECIFIED=2 不是字符串 + createCameraInput 工厂造 CameraInput(interface 不能 new)+ open() 异步打开相机 + CameraType enum 常量 CAMERA_TYPE_WIDE_ANGLE=0/TELEPHOTO=1/ULTRA_WIDE=2/DEFAULT=3 不是字符串 + createPreviewOutput 工厂造 PreviewOutput(interface 不能 new)+ surfaceId 来自 XComponent + Profile 用 getSupportedOutputCapability().previewProfiles[0] + CameraFormat enum 常量 CAMERA_FORMAT_RGBA_8888=3/YUV_420_SP=1003/JPEG=2000 不是字符串 + createCaptureSession 工厂造 CaptureSession(interface 不能 new)+ 会话流程 5 步 beginConfig→addInput→addOutput→commitConfig→start 严格顺序 + aboutToDisappear 生命周期 stop+close+release 释放资源(本文)
更多推荐


所有评论(0)