import { camera, cameraPicker } from '@kit.CameraKit';
import { image } from '@kit.ImageKit';
import { JSON } from '@kit.ArkTS';
import Logger from '../../UtilClass/LoggerUtils';
import { BusinessError } from '@kit.BasicServicesKit';
import { common } from '@kit.AbilityKit';
const TAG: string = 'CameraService';
/**
* 相机服务
*
*@author liu 2025/05/12
*/
class CameraService {
private cameraManager: camera.CameraManager | undefined = undefined;
private cameras: Array<camera.CameraDevice> | Array<camera.CameraDevice> = [];
private cameraInput: camera.CameraInput | undefined = undefined;
private previewOutput: camera.PreviewOutput | undefined = undefined;
private session: camera.PhotoSession | camera.VideoSession | undefined = undefined;
private curCameraDevice: camera.CameraDevice | undefined = undefined;
private receiver: image.ImageReceiver | undefined = undefined;
private width: number = 1920;
private height: number = 1080;
frameStartFlag: number = 0;
private finalPixelMap: image.PixelMap | undefined = undefined;
private imageSize: image.Size = { width: 1920, height: 1080 };
/**
* 初始化相机功能
* @param cameraDeviceIndex - 相机设备索引
* @returns 无返回值
*/
async initCamera(cameraDeviceIndex: number, xComponentSurfaceId: string): Promise<void> {
Logger.debug(TAG, `initCamera cameraDeviceIndex: ${cameraDeviceIndex}`);
try {
await this.releaseCamera();
// 获取相机管理器实例
this.cameraManager = this.getCameraManagerFn();
if (this.cameraManager === undefined) {
Logger.error(TAG, 'cameraManager is undefined');
return;
}
this.cameras = this.getSupportedCamerasFn(this.cameraManager);
this.curCameraDevice = this.cameras[cameraDeviceIndex];
if (this.curCameraDevice === undefined) {
Logger.error(TAG, 'Failed to create the camera input.');
return;
}
// 创建cameraInput输出对象
this.cameraInput = this.createCameraInputFn(this.cameraManager, this.curCameraDevice);
if (this.cameraInput === undefined) {
Logger.error(TAG, 'Failed to create the camera input.');
return;
}
// 打开相机
let isOpenSuccess = await this.cameraInputOpenFn(this.cameraInput);
if (!isOpenSuccess) {
Logger.error(TAG, 'Failed to open the camera.');
return;
}
// 选择具有不同的stride和width
let previewProfile: camera.Profile = {
format: camera.CameraFormat.CAMERA_FORMAT_YUV_420_SP,
size: {
width: this.width,
height: this.height
}
};
let size: image.Size = {
width: this.width,
height: this.height
}
this.receiver = image.createImageReceiver(size, image.ImageFormat.JPEG, 8);
this.previewOutput = this.createPreviewOutputFn(this.cameraManager, previewProfile, xComponentSurfaceId);
// 会话流
await this.sessionFlowFn(this.cameraManager, this.cameraInput, this.previewOutput);
} catch (error) {
Logger.error(TAG, `initCamera fail: ${JSON.stringify(error)}`);
}
}
setPhotoOutputCb(photoOutput: camera.PhotoOutput) {
//设置回调之后,调用photoOutput的capture方法,就会将拍照的buffer回传到回调中
photoOutput.on('photoAvailable', (errCode: BusinessError, photo: camera.Photo): void => {
console.info(`CameraDemo getPhoto start. err: ${JSON.stringify(errCode)}`);
if (errCode || photo === undefined || photo.main === undefined) {
console.error('CameraDemo getPhoto failed');
return;
}
let imageObj = photo.main;
imageObj.getComponent(image.ComponentType.JPEG,
async (errCode: BusinessError, component: image.Component): Promise<void> => {
console.info('CameraDemo getComponent start');
if (errCode || component === undefined) {
console.error('CameraDemo getComponent failed');
return;
}
let imageBuffer: ArrayBuffer;
if (component.byteBuffer) {
imageBuffer = component.byteBuffer;
let sourceOptions: image.SourceOptions = {
sourceDensity: 0,
sourcePixelFormat: image.PixelMapFormat.RGBA_8888,
sourceSize: this.imageSize
}
let imageSource: image.ImageSource = image.createImageSource(imageBuffer, sourceOptions);
let opts: image.InitializationOptions = {
editable: false,
pixelFormat: image.PixelMapFormat.RGBA_8888,
size: this.imageSize
}
let pixelMap = await imageSource.createPixelMap(opts);
this.finalPixelMap = pixelMap;
} else {
return;
}
});
});
}
/**
* 释放会话和相关参数
*/
async releaseCamera(): Promise<void> {
Logger.info(TAG, 'releaseCamera is called');
try {
await this.receiver?.release();
} catch (err) {
Logger.error(TAG, `imageReceiver release fail: error: ${JSON.stringify(err)}`);
}
try {
await this.previewOutput?.release();
} catch (err) {
Logger.error(TAG, `previewOutput release fail: error: ${JSON.stringify(err)}`);
} finally {
this.previewOutput = undefined;
}
try {
await this.session?.release();
} catch (err) {
Logger.error(TAG, `captureSession release fail: error: ${JSON.stringify(err)}`);
} finally {
this.session = undefined;
}
try {
await this.cameraInput?.close();
} catch (err) {
Logger.error(TAG, `cameraInput close fail: error: ${JSON.stringify(err)}`);
} finally {
this.cameraInput = undefined;
}
Logger.info(TAG, 'releaseCamera success');
}
/**
* 获取相机管理器实例
*/
getCameraManagerFn(): camera.CameraManager | undefined {
if (this.cameraManager) {
return this.cameraManager;
}
let cameraManager: camera.CameraManager | undefined = undefined;
try {
cameraManager = camera.getCameraManager(getContext(this));
Logger.info(TAG, `getCameraManager success: ${cameraManager}`);
} catch (error) {
Logger.error(TAG, `getCameraManager failed: ${JSON.stringify(error)}`);
}
return cameraManager;
}
/**
* 获取支持指定的摄像机设备对象
*/
getSupportedCamerasFn(cameraManager: camera.CameraManager): Array<camera.CameraDevice> {
let supportedCameras: Array<camera.CameraDevice> = [];
try {
supportedCameras = cameraManager.getSupportedCameras();
Logger.info(TAG, `getSupportedCameras success: ${this.cameras}, length: ${this.cameras?.length}`);
} catch (error) {
Logger.error(TAG, `getSupportedCameras failed: ${JSON.stringify(error)}`);
}
return supportedCameras;
}
/**
* 创建cameraInput输出对象
*/
createCameraInputFn(cameraManager: camera.CameraManager,
cameraDevice: camera.CameraDevice): camera.CameraInput | undefined {
Logger.info(TAG, 'createCameraInputFn is called.');
let cameraInput: camera.CameraInput | undefined = undefined;
try {
cameraInput = cameraManager.createCameraInput(cameraDevice);
Logger.info(TAG, 'createCameraInputFn success');
} catch (error) {
Logger.error(TAG, `createCameraInputFn failed: ${JSON.stringify(error)}`);
}
return cameraInput;
}
/**
* 创建previewOutput输出对象
*/
createPreviewOutputFn(cameraManager: camera.CameraManager, previewProfileObj: camera.Profile,
surfaceId: string): camera.PreviewOutput | undefined {
let previewOutput: camera.PreviewOutput | undefined = undefined;
try {
previewOutput = cameraManager.createPreviewOutput(previewProfileObj, surfaceId);
Logger.info(TAG, `createPreviewOutput success: ${previewOutput}`);
} catch (error) {
Logger.error(TAG, `createPreviewOutput failed: ${JSON.stringify(error)}`);
}
return previewOutput;
}
/**
* 打开相机
*/
async cameraInputOpenFn(cameraInput: camera.CameraInput): Promise<boolean> {
let isOpenSuccess = false;
try {
await cameraInput.open();
isOpenSuccess = true;
Logger.info(TAG, 'cameraInput open success');
} catch (error) {
Logger.error(TAG, `createCameraInput failed : ${JSON.stringify(error)}`);
}
return isOpenSuccess;
}
/**
* 会话流
*/
async sessionFlowFn(cameraManager: camera.CameraManager, cameraInput: camera.CameraInput,
previewOutput: camera.PreviewOutput | undefined): Promise<void> {
try {
// 创建CaptureSession实例
this.session = cameraManager.createSession(camera.SceneMode.NORMAL_PHOTO) as camera.PhotoSession;
this.session.beginConfig();
this.session.addInput(cameraInput);
this.session.addOutput(previewOutput);
await this.session.commitConfig();
await this.session.start();
Logger.info(TAG, 'sessionFlowFn success');
} catch (error) {
Logger.error(TAG, `sessionFlowFn fail : ${JSON.stringify(error)}`);
}
}
async pickUpCamera(context:common.Context):Promise<string> {
let pickRes: Promise<string> = new Promise((resolve, reject) => {
let pickerProfile: cameraPicker.PickerProfile = {
cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK
};
cameraPicker.pick(context, [cameraPicker.PickerMediaType.PHOTO], pickerProfile).then((res) => {
if(res.resultCode === 0) {
resolve(res.resultUri);
}else {
reject(res.resultCode);
}
}).catch((err: BusinessError) => {
reject(err);
})
})
return pickRes;
}
}
export default new CameraService();