HarmonyOS 鸿蒙Next 自定义相机在 mete60, mete40 正常,在 x5 设备黑屏
HarmonyOS 鸿蒙Next 自定义相机在 mete60, mete40 正常,在 x5 设备黑屏
相机工具类
导入模块
import camera from '@ohos.multimedia.camera';
import image from '@ohos.multimedia.image';
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
import { AppInfo, DeviceInfo } from 'lib_paoh_baseinfo';
import { savePictureToAlbum } from '../Photo/SaveImage';
import fileUri from '@ohos.file.fileuri';
const TAG: string = 'CAMERA_TAG';
let cameraManager: camera.CameraManager;
let photoOutput: camera.PhotoOutput;
let captureSession: camera.CaptureSession;
let cameraInput: camera.CameraInput;
let previewOutput: camera.PreviewOutput;
let cameraDevice: camera.CameraDevice
let imageReceiver: image.ImageReceiver
let context: ESObject
CameraConfig 类
export class CameraConfig {
saveToAlbum: boolean = true
saveToSandbox: Boolean = true
handleTakePicture: (photoUri: string) => void = this._handleTakePicture
_handleTakePicture(uri: string): void {
Logger.info(TAG, `_handleTakePicture uri = ${uri}`)
}
}
CameraService 类
export class CameraService {
config: CameraConfig = new CameraConfig()
constructor(config: CameraConfig) {
this.config = config
}
async initCamera(baseContext: ESObject, surfaceId: string) {
try {
await this._initCamera(baseContext,surfaceId)
} catch (error) {
Logger.error(TAG, `Camera error : ${JSON.stringify(error)}`);
}
}
async _initCamera(baseContext: ESObject, surfaceId: string) {
cameraManager = camera.getCameraManager(baseContext);
let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
cameraDevice = cameraArray[0];
cameraInput = cameraManager.createCameraInput(cameraDevice);
await cameraInput.open();
let cameraOutputCap: camera.CameraOutputCapability = cameraManager.getSupportedOutputCapability(cameraDevice);
let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles;
let position: number = this._profilesPosition(previewProfilesArray)
let previewProfile = previewProfilesArray[position]
let photoProfilesArray: Array<camera.Profile> = cameraOutputCap.photoProfiles;
let photoProfile = photoProfilesArray[photoProfilesArray.length - 1]
imageReceiver = image.createImageReceiver(previewProfile.size.width, previewProfile.size.height, 4, 8);
let photoSurfaceId: string = await imageReceiver.getReceivingSurfaceId();
photoOutput = cameraManager.createPhotoOutput(photoProfile, photoSurfaceId);
previewOutput = cameraManager.createPreviewOutput(previewProfile, surfaceId);
captureSession = cameraManager.createCaptureSession();
captureSession.beginConfig();
captureSession.addInput(cameraInput);
captureSession.addOutput(previewOutput);
captureSession.addOutput(photoOutput);
await captureSession.commitConfig();
await captureSession.start()
this._monitorCameraState()
}
capture() {
let photoCaptureSetting: camera.PhotoCaptureSetting = {
quality: camera.QualityLevel.QUALITY_LEVEL_HIGH,
}
photoOutput.capture(photoCaptureSetting, (err: BusinessError) => {
if (err) {
Logger.error(TAG, `Failed to capture the photo ${err.message}`);
return;
}
Logger.info(TAG, 'Callback invoked to indicate the photo capture request success.');
});
}
releaseCamera() {
captureSession.stop();
cameraInput.close();
previewOutput.release();
photoOutput.release();
captureSession.release();
}
async savePictureToAlbum(buffer: ArrayBuffer) {
const photoSaveOptions = new picker.PhotoSaveOptions();
let photoUri = await savePictureToAlbum(buffer)
if (this.config.handleTakePicture) {
this.config.handleTakePicture(photoUri)
}
}
async savePictureToSandbox(buffer: ArrayBuffer) {
let imageName = "IMG_" + Date.parse(new Date().toString()) + ".jpg";
let context = getContext() as common.UIAbilityContext;
let path = context.filesDir + "/" + imageName;
Logger.info(TAG, "图片路径:" + path);
let file = fs.openSync(path, fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE)
let value = fs.writeSync(file.fd, buffer)
fs.closeSync(file);
if (value !== -1) {
Logger.info(TAG, "图片保存成功")
let imageUri: string = fileUri.getUriFromPath(path);
Logger.info(TAG, "imageUri->" + imageUri.toString())
if (this.config.handleTakePicture) {
this.config.handleTakePicture(imageUri)
}
}
}
_monitorCameraState() {
cameraManager.on('cameraStatus', (err: BusinessError, cameraStatusInfo: camera.CameraStatusInfo) => {
Logger.info(TAG, `camera : ${cameraStatusInfo.camera.cameraId}`);
Logger.info(TAG, `status: ${cameraStatusInfo.status}`);
});
cameraInput.on('error', cameraDevice, (error: BusinessError) => {
Logger.error(TAG, `Camera input error code: ${error.code}`);
})
previewOutput.on('error', (error: BusinessError) => {
Logger.error(TAG, `Preview output error code: ${error.code}`);
});
photoOutput.on('captureEnd', (err: BusinessError, data: camera.CaptureEndInfo) => {
Logger.info(TAG, `photoOutput ${err}`)
})
captureSession.on('error', (error: BusinessError) => {
Logger.error(TAG, `Capture session error code: ${error.code}`);
});
imageReceiver.on('imageArrival', async () => {
try {
let nextImage: image.Image = await imageReceiver.readNextImage()
let imgComponent: image.Component = await nextImage.getComponent(image.ComponentType.JPEG)
if (!(imgComponent.byteBuffer as ArrayBuffer)) {
return
}
Logger.info(TAG, "接收到图片数据[" + imgComponent.byteBuffer.byteLength + "]")
if(this.config.saveToAlbum) await this.savePictureToAlbum(imgComponent.byteBuffer)
if(this.config.saveToSandbox) await this.savePictureToSandbox(imgComponent.byteBuffer)
nextImage.release()
} catch (error) {
Logger.error(TAG, `imageArrival error = ${error}} `)
}
})
}
_profilesPosition(previewProfilesArray: Array<camera.Profile>): number {
let position: number = 0
let difference:number = Number.MAX_VALUE;
if (previewProfilesArray != null) {
previewProfilesArray.forEach((value: camera.Profile, index: number) => {
let previewWidth = value.size.width
let previewHeight = value.size.height
let aspectRatio = previewWidth / previewHeight * 1000 / 1000;
if (aspectRatio < 1) {
aspectRatio = previewHeight / previewWidth * 1000 / 1000;
}
let device_width = DeviceInfo.getResolution().width
let device_height = DeviceInfo.getResolution().height
let device_aspectRatio = device_width / device_height * 1000 / 1000;
if (device_aspectRatio < 1) {
device_aspectRatio = device_height / device_width * 1000 / 1000;
}
let _difference = Math.abs(device_aspectRatio - aspectRatio);
if (difference > _difference) {
difference = _difference
position = index;
}
})
}
return position
}
}
更多关于HarmonyOS 鸿蒙Next 自定义相机在 mete60, mete40 正常,在 x5 设备黑屏的实战教程也可以访问 https://www.itying.com/category-93-b0.html
4 回复
这是处理器的问题,后续新版本都会适配好
更多关于HarmonyOS 鸿蒙Next 自定义相机在 mete60, mete40 正常,在 x5 设备黑屏的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
大佬,咨询一下 预览配置如何选择最优 配置, cameraOutputCap.previewProfiles
里面有几十个配置,要怎么选
配置 相机输出 预览配置
let previewProfilesArray: Array<camera.Profile> = cameraOutputCap.previewProfiles;
在HarmonyOS鸿蒙Next中,自定义相机在Mate 60和Mate 40设备上正常运行,但在X5设备上出现黑屏问题。可能的原因包括设备硬件差异、相机API兼容性问题、权限配置错误或资源文件缺失。X5设备的相机模块或传感器可能与Mate系列不同,导致API调用失败。此外,HarmonyOS在不同设备上的实现可能存在差异,某些API在X5设备上可能未完全支持或存在bug。权限配置错误或资源文件缺失也可能导致相机无法正常初始化。