Harmony Next 和 OpenHarmony 相机手动变焦(点击屏幕设置对焦点) 原创
msdone
发布于 2024-11-20 18:00
浏览
0收藏
目录
概述
已在 Harmony Next (mate 60) 上测试通过
源码采用 openharmony 社区相机代码,https://gitee.com/openharmony/applications_app_samples/tree/master/code/SystemFeature/Media/Camera,由于在 Harmony Next 上测试,社区源码语法适配修改较多,所以删减了一些功能,专注于实现点击屏幕设置对焦点的功能,且这里只贴出修改最多(最核心)的几个个文件:
- entry/src/main/ets/pages/Camera.ets
- entry/src/main/ets/model/CameraModel.ts
- entry/src/main/ets/utlis/UIUtils.ets
由于 setFocusPoint 接口规定,坐标在0-1坐标系内,需要使用文档中计算方法{y/h,1-x/w},才能计算出合理的 point 值
这里的 w、h指的是 xComponent 组件竖屏状态的 宽高, x、y指的是竖屏状态触摸事件的 x、y,不需要去手动调换 w 和 h 的值、 x 和 y 的值
按照文档的提示,左上角为{0,0},右下角为{1,1}。则知道屏幕四个角的值(横屏状态下):
- 左上角:接近 0,0
- 左下角:接近 0,1
- 右上角:接近 1,0
- 右上角:接近 1,1
可以通过先点击某一角、然后点击 getFocusPoint 按钮获取 ponit 的值,查看值是否与预期的相符。
Camera.ets
import prompt from '@ohos.promptAction';
import camera from '@ohos.multimedia.camera';
import CameraModel from '../model/CameraModel';
import { VideoFrame } from '../model/CameraModel';
import Title from '../component/TitleComponent';
import grantPermission from '../utlis/PermissionUtils';
import Logger from '../utlis/Logger';
import { GlobalContext } from '../utlis/GlobalContext'
import { BusinessError } from '@ohos.base';
import common from '@ohos.app.ability.common';
import { deviceInfoManager } from '../utlis/DeviceInfo';
import { uiUtilsManager } from '../utlis/UIUtils';
enum CameraMode {
modePhoto = 0, // 拍照模式
modeVideo = 1 // 录像模式
};
const TAG: string = '[CameraPage]';
@Entry
@Component
struct CameraPage {
private mXComponentController: XComponentController = new XComponentController();
private surfaceId: string = '-1';
@State cameraModel: CameraModel = new CameraModel();
@State imageThumbnail: string = '';
@State videoThumbnail: Resource | undefined = undefined;
@State currentModel: number = CameraMode.modePhoto;
@State isRecording: boolean = false;
@State textMove: number = 45;
@State isPointShow: boolean = true;
@State isTitleShow: boolean = true;
@StorageLink('selectType_0') @Watch('rotationChange') rotation: number = 0;
@StorageLink('selectType_1') @Watch('resolutionChange') resolution: number = 0;
@State timeShow: boolean = false;
private textTimerController: TextTimerController = new TextTimerController();
@State format: string = 'mm:ss';
@State fps: number = 0;
/**
* 旋转角度改变监听方法
*/
rotationChange() {
Logger.info(TAG, `rotationChange begin ${this.rotation}`);
// 0°
if (this.rotation == 0) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_0);
// 90°
} else if (this.rotation == 1) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_90);
// 180°
} else if (this.rotation == 2) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_180);
// 270°
} else if (this.rotation == 3) {
Logger.info(TAG, `rotationChange ${this.rotation}`);
this.cameraModel.setImageRotation(camera.ImageRotation.ROTATION_270);
}
Logger.info(TAG, 'rotationChange end');
}
/**
* 分辨率改变监听方法
*/
resolutionChange() {
Logger.info(TAG, `resolutionChange begin ${this.resolution}`);
// 不支持 则为默认800*600
if (this.resolution == 0) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_1920_1080);
} else if (this.resolution == 1) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_1920_1080);
// 1280*720
} else if (this.resolution == 2) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_1280_720);
// 800*600
} else if (this.resolution == 3) {
Logger.info(TAG, `resolutionChange ${this.resolution}`);
this.cameraModel.setVideoFrameWH(VideoFrame.VIDEOFRAME_800_600);
}
Logger.info(TAG, 'resolutionChange end');
}
async aboutToAppear() {
this.cameraModel.setCallback((fps: number) => {
this.fps = fps;
})
await grantPermission().then(res => {
Logger.info(TAG, `权限申请成功 ${JSON.stringify(res)}`);
if (this.surfaceId) {
this.cameraModel.initCamera(this.surfaceId);
}
}).catch((rej: BusinessError) => {
Logger.info(TAG, `权限申请失败 ${JSON.stringify(rej)}`);
})
this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
Logger.info(TAG, `aboutToAppear,surfaceId=${this.surfaceId}`);
this.cameraModel.setTakePictureHandleCallback((photoUri: string): void => this.takePictureHandle(photoUri));
}
onPageHide() {
Logger.info(TAG, 'onPageHide begin');
if (this.isRecording) {
Logger.info(TAG, 'stopVideo begin');
this.timeShow = false;
this.textTimerController.pause();
this.cameraModel.stopVideo();
this.isRecording = false;
this.cameraModel.cameraRelease();
this.videoThumbnail = $r('app.media.video_poster');
}
Logger.info(TAG, 'onPageHide end');
}
onPageShow() {
this.cameraModel.initCamera(this.surfaceId);
}
getCameraIcon() {
if (this.currentModel === CameraMode.modePhoto) {
return $r('app.media.take_photo_normal');
} else {
if (this.isRecording) {
return $r('app.media.take_video_stop');
} else {
return $r('app.media.take_video_normal');
}
}
}
refreshVideoState() {
if (this.isRecording) {
Logger.info(TAG, 'stopVideo begin');
this.timeShow = false;
this.textTimerController.pause();
this.cameraModel.stopVideo();
this.isRecording = false;
this.videoThumbnail = $r('app.media.video_poster');
} else {
Logger.info(TAG, 'startVideo begin');
this.timeShow = true;
this.textTimerController.reset();
this.textTimerController.start();
this.cameraModel.startVideo();
this.isRecording = true;
}
}
startAbilityToPhoto() {
(GlobalContext.getContext().getCameraAbilityContext() as common.UIAbilityContext).startAbility({
bundleName: 'com.ohos.photos',
abilityName: 'com.ohos.photos.MainAbility'
}, (error: BusinessError) => {
Logger.info(TAG, `error.code = ${error.code}`)
});
}
takePictureHandle = (thumbnail: string) => {
this.imageThumbnail = thumbnail;
Logger.info(TAG, `takePicture end , thumbnail: ${this.imageThumbnail}`);
};
animateParam: AnimateParam = {
duration: 500,
onFinish: () => {
this.isPointShow = true;
}
};
/**
* 拍照事件
*/
photoEvent() {
if (this.currentModel === CameraMode.modeVideo) {
animateTo(this.animateParam, () => {
this.isPointShow = false;
this.textMove = this.textMove + 56;
});
if (this.isRecording) {
this.timeShow = false;
this.isRecording = false;
this.cameraModel.stopVideo();
}
this.currentModel = CameraMode.modePhoto;
this.videoThumbnail = undefined;
this.cameraModel.initCamera(this.surfaceId);
}
}
/**
* 录像事件
*/
videoEvent() {
if (this.currentModel === CameraMode.modePhoto) {
animateTo(this.animateParam, () => {
this.isPointShow = false;
this.textMove = this.textMove - 56;
});
this.currentModel = CameraMode.modeVideo;
this.imageThumbnail = '';
}
}
build() {
Stack() {
XComponent({
id: 'componentId',
type: 'surface',
controller: this.mXComponentController
})
.onLoad(() => {
Logger.info(TAG, 'onLoad is called');
this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: 2560, surfaceHeight: 1440 });
this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
Logger.info(TAG, `onLoad surfaceId: ${this.surfaceId}`);
this.currentModel = CameraMode.modePhoto;
this.cameraModel.initCamera(this.surfaceId);
})
// .width('1216px')
// .height('1216px')
// .width('480px')
// .height('480px')
.width('100%')
.height('100%')
.id('xComponentUI')
.gesture(
GestureGroup(GestureMode.Parallel,
TapGesture({ count: 1, fingers: 1 })
.onAction((e) => {
// Logger.info(TAG, `screenWidth: ${deviceInfoManager.getScreenWidth()}, screenHeight: ${deviceInfoManager.getScreenHeight()}, screenRefreshRate: ${deviceInfoManager.getScreenRefreshRate()}, deviceApiVersion: ${deviceInfoManager.getDeviceApiVersion()}`);
if (!this.cameraModel.isSupportFocusMode()) {
Logger.info(TAG, 'not support focus mode');
return;
}
let size = uiUtilsManager.extractComponentSizeByID("xComponentUI")
let w = size[0];
let h = size[1];
let x = vp2px(e.fingerList[0].localX);
let y = vp2px(e.fingerList[0].localY);
Logger.info(TAG, `x: ${x}, y: ${y}, w: ${w}, h: ${h}`);
this.cameraModel.setFocusPoint( y / h, 1 - x / w);
}),
SwipeGesture({ direction: SwipeDirection.Horizontal, speed: 40 })
.onAction((event: GestureEvent) => {
Logger.info(TAG, `SwipeGesture event: ${JSON.stringify(event)}`);
// 右滑
if (event.angle > 0) {
this.photoEvent();
} else {
this.videoEvent();
}
})
)
)
Column() {
Text(this.fps.toString())
.fontSize(30)
.backgroundColor(Color.Red)
Row() {
Button("start")
.onClick(async () => {
await this.cameraModel.listenFPS();
})
Button("stop")
.onClick(async () => {
await this.cameraModel.unlistenFPS();
})
Button("getFocusPoint")
.onClick(async () => {
this.cameraModel.getFocusPoint();
})
}
}
}
.width('100%')
.height('100%')
.alignSelf(ItemAlign.End)
.alignContent(Alignment.Bottom)
.align(Alignment.Bottom)
}
async aboutToDisappear() {
if (this.isRecording) {
await this.cameraModel.stopVideo();
}
await this.cameraModel.cameraRelease();
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
CameraModel.ts
import camera from '@ohos.multimedia.camera';
import deviceInfo from '@ohos.deviceInfo';
import fileIo from '@ohos.file.fs';
import image from '@ohos.multimedia.image';
import media from '@ohos.multimedia.media';
import photoAccessHelper from '@ohos.file.photoAccessHelper';
import Logger from '../utlis/Logger';
import MediaModel from './MediaModel';
import prompt from '@ohos.prompt';
import { BusinessError } from '@ohos.base';
import { logger } from '../../../ohosTest/ets/util/Logger';
const FOUR = 4; // format
const EIGHT = 8; // capacity
const FOUR_THOUSAND_AND_SIXTY_NINE = 4096; // buffer大小
const cameraMode = {
modePhoto: 0, // 拍照模式
modeVideo: 1, // 录像模式
};
const cameraWH = {
width: 2560,
height: 1440,
};
/**
* 分辨率
*/
export enum VideoFrame {
VIDEOFRAME_1920_1080,
VIDEOFRAME_1280_720,
VIDEOFRAME_800_600,
};
type VideoFrameWH = {
width: number;
height: number;
};
const TAG = '[CameraModel]';
export default class CameraService {
private mediaModel: MediaModel = undefined;
private fileAsset: photoAccessHelper.PhotoAsset | undefined = undefined;
private cameraMgr: camera.CameraManager = undefined;
private camerasArray: Array<camera.CameraDevice> = undefined;
private cameraInput: camera.CameraInput = undefined;
private previewOutput: camera.PreviewOutput = undefined;
private previewOutput2: camera.PreviewOutput = undefined;
// private capSession: camera.Session = undefined;
private capSession: camera.PhotoSession = undefined;
private videoOutput: camera.VideoOutput = undefined;
private capability: camera.CameraOutputCapability = undefined;
private avRecorder: media.AVRecorder = undefined;
private receiver: image.ImageReceiver = undefined;
private photoPath: string = '';
private fd: number = -1;
private takePictureHandle: (photoUri: string) => void = undefined;
private currentMode:number = cameraMode.modePhoto;
private frame_times: number[] = [];
private last_time: number = 0;
private sum: number = 0;
private isListen: boolean = false;
private previewProfile2: camera.Profile | undefined = undefined;
private round(value: number, decimals: number): number {
const factor = Math.pow(10, decimals);
return Math.round(value * factor) / factor;
}
private fps: number = 0;
private videoFrameWH: VideoFrameWH = {
// width: 480,
// height: 360,
width: 2560,
height: 1440,
}; // 视频分辨率
private imageRotation: camera.ImageRotation = camera.ImageRotation.ROTATION_0; // 图片旋转角度
private videoProfile: media.AVRecorderProfile = {
audioChannels: 2,
audioCodec: media.CodecMimeType.AUDIO_AAC,
audioBitrate: 48000,
audioSampleRate: 48000,
fileFormat: media.ContainerFormatType.CFT_MPEG_4,
videoBitrate: 48000,
videoCodec: media.CodecMimeType.VIDEO_AVC,
videoFrameWidth: 2560,
videoFrameHeight: 1440,
videoFrameRate: 30,
};
private videoSourceType: number = 0;
callback: (fps: number) => void;
setCallback(callback: (fps: number) => void) {
this.callback = callback;
}
async listenFPS() {
if (this.isListen) {
return;
}
this.isListen = true;
this.receiver = image.createImageReceiver(
cameraWH.width,
cameraWH.height,
FOUR,
EIGHT
//
// image.ImageFormat.JPEG,
// 1
);
Logger.info(TAG, 'imageArrival: receiver:' + JSON.stringify(this.receiver));
if (!this.receiver) {
Logger.error(TAG, 'imageArrival: failed to create receiver');
}
this.receiver.on('imageArrival', () => {
Logger.info(TAG, 'imageArrival');
this.receiver?.readNextImage((err: BusinessError, nextImage: image.Image) => {
if (err || nextImage === undefined || this.isListen === false) {
return;
}
nextImage.getComponent(image.ComponentType.JPEG, async (err: BusinessError, imgComponent: image.Component) => {
if (err || imgComponent === undefined) {
return;
}
console.log(TAG + `20241115 FPS LOG ==> buffer success`);
try {
if (this.last_time === 0) {
this.last_time = Date.now(); // ms
return;
}
let current_time = Date.now();
console.log('20241115 FPS LOG ====> current_time:', current_time);
let frame_time = current_time - this.last_time;
console.log('20241115 FPS LOG ====> frame_time:', frame_time);
this.last_time = current_time;
console.log('20241115 FPS LOG ====> last_time:', this.last_time);
if (frame_time > 0 && frame_time < 1000) { // 添加合理性检查,帧时间应该在 0-1000ms 之间
this.frame_times.push(frame_time);
console.log('20241115 FPS LOG ====> frame_times:', this.frame_times);
if (this.frame_times.length > 60) {
this.sum -= this.frame_times.shift()!;
this.sum += frame_time;
} else {
this.sum += frame_time;
}
console.log('20241115 FPS LOG ====> sum:', this.sum);
let avg_frame_time = this.sum / this.frame_times.length;
console.log('20241115 FPS LOG ====> avg_frame_time:', avg_frame_time);
let fps = 1000.0 / avg_frame_time; // 秒转换为毫秒并计算 FPS
console.log('20241115 FPS LOG ====> fps:', fps);
this.fps = this.round(fps, 1);
console.log('20241115 FPS LOG ====> fps:', this.fps);
this.callback(this.fps);
}
nextImage.release();
console.log(TAG + `20241115 FPS LOG ==> release successfully`);
} catch (e) {
console.log(TAG + `20241115 FPS LOG ==> release error: ${JSON.stringify(e)}`);
}
})
})
});
Logger.info(TAG, 'imageArrival END');
let imageReceiveSurfaceId: string = await this.receiver?.getReceivingSurfaceId() ?? "";
Logger.info("imageArrival: imageReceiveSurfaceId: " + imageReceiveSurfaceId);
this.previewOutput2 = this.cameraMgr?.createPreviewOutput(this.previewProfile2, imageReceiveSurfaceId);
await this.capSession.stop();
this.capSession.beginConfig();
Logger.info(TAG, 'beginConfig');
// this.capSession.addInput(this.cameraInput);
// this.capSession.addOutput(this.previewOutput);
this.capSession.addOutput(this.previewOutput2);
await this.capSession.commitConfig();
await this.capSession.start();
}
async unlistenFPS() {
this.isListen = false;
this.frame_times = [];
this.fps = 0;
this.last_time = 0;
this.sum = 0;
try {
await this.receiver?.release();
this.capSession.beginConfig();
this.capSession.removeOutput(this.previewOutput2);
await this.capSession.commitConfig();
await this.capSession.start();
this.callback(0);
Logger.info(TAG, 'unlistenFPS: release receiver success');
} catch (e) {
Logger.error(TAG, 'unlistenFPS: release receiver error: ' + JSON.stringify(e));
}
}
constructor() {
this.mediaModel = MediaModel.getMediaInstance();
this.receiver = image.createImageReceiver(
cameraWH.width,
cameraWH.height,
FOUR,
EIGHT
//
// image.ImageFormat.JPEG,
// 1
);
Logger.info(TAG, 'imageArrival: receiver:' + JSON.stringify(this.receiver));
if (!this.receiver) {
Logger.error(TAG, 'imageArrival: failed to create receiver');
}
}
/**
* 设置分辨率
* @param videoFrame
*/
setVideoFrameWH(videoFrame: VideoFrame): void {
switch (videoFrame) {
case VideoFrame.VIDEOFRAME_800_600:
this.videoFrameWH = {
// width: 800,
// height: 600,
width: 2560,
height: 1440,
};
Logger.info(
TAG,
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
);
break;
case VideoFrame.VIDEOFRAME_1280_720:
this.videoFrameWH = {
// width: 1280,
// height: 720,
width: 2560,
height: 1440,
};
Logger.info(
TAG,
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
);
break;
case VideoFrame.VIDEOFRAME_1920_1080:
this.videoFrameWH = {
// width: 1920,
// height: 1080,
width: 2560,
height: 1440,
};
Logger.info(
TAG,
`setVideoFrameWH videoFrameWH:${JSON.stringify(this.videoFrameWH)}`
);
break;
}
}
/**
* 设置图片旋转角度
* @param imageRotation
*/
setImageRotation(imageRotation: camera.ImageRotation): void {
this.imageRotation = imageRotation;
}
/**
* 保存图片
* @param buffer
* @param img
*/
async saveImage(buffer: ArrayBuffer, img: image.Image): Promise<void> {
// Logger.info(TAG, 'savePicture');
// this.fileAsset = await this.mediaModel.createAndGetUri(photoAccessHelper.PhotoType.IMAGE);
// this.photoPath = this.fileAsset.uri;
// Logger.info(TAG, `this.photoUri = ${this.photoPath}`);
// this.fd = await this.mediaModel.getFdPath(this.fileAsset);
// Logger.info(TAG, `this.fd = ${this.fd}`);
// await fileIo.write(this.fd, buffer);
// await this.fileAsset.close(this.fd);
// await img.release();
// Logger.info(TAG, 'save image done');
// if (this.takePictureHandle) {
// this.takePictureHandle(this.photoPath);
// }
}
isSupportFocusMode() {
try{
let re = this.capSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_AUTO);
Logger.info(TAG, 'isSupportFocusMode: ' + re);
return re;
} catch (e) {
Logger.error(TAG, 'isSupportFocusMode error: ' + JSON.stringify(e));
}
}
setFocusPoint(x: number, y: number) {
try {
this.capSession.setFocusPoint({x: x, y: y});
Logger.info(TAG, 'setFocusPoint success: x=' + x + ', y=' + y);
} catch (e) {
Logger.error(TAG, 'setFocusPoint error: ' + JSON.stringify(e));
}
}
getFocusPoint() {
try {
let focusPoint = this.capSession.getFocusPoint();
prompt.showToast({
message: 'getFocusPoint: ' + JSON.stringify(focusPoint),
});
} catch(e) {
prompt.showToast({
message: 'getFocusPoint error' + JSON.stringify(e)
})
}
}
/**
* 初始化相机
* @param surfaceId
*/
async initCamera(surfaceId: string): Promise<void> {
Logger.info(TAG, `initCamera surfaceId:${surfaceId}`);
await this.cameraRelease();
Logger.info(TAG, `deviceInfo.deviceType = ${deviceInfo.deviceType}`);
if (deviceInfo.deviceType === 'default') {
Logger.info(TAG, `deviceInfo.deviceType default 1 = ${deviceInfo.deviceType}`);
this.videoSourceType = 1;
Logger.info(TAG, `deviceInfo.deviceType default 2 = ${deviceInfo.deviceType}`);
} else {
Logger.info(TAG, `deviceInfo.deviceType other 1 = ${deviceInfo.deviceType}`);
this.videoSourceType = 0;
Logger.info(TAG, `deviceInfo.deviceType other 2 = ${deviceInfo.deviceType}`);
}
Logger.info(TAG, 'getCameraManager begin');
try {
Logger.info(TAG, 'getCameraManager try begin');
this.cameraMgr = camera.getCameraManager(globalThis.cameraContext);
Logger.info(TAG, 'getCameraManager try end');
} catch (e) {
Logger.info(TAG, `getCameraManager catch e:${JSON.stringify(e)}`);
Logger.info(TAG, `getCameraManager catch code:${JSON.stringify(e.code)}`);
Logger.info(TAG, `getCameraManager catch message:${JSON.stringify(e.message)}`);
}
Logger.info(TAG, 'getCameraManager end');
Logger.info(TAG, `getCameraManager ${JSON.stringify(this.cameraMgr)}`);
this.camerasArray = this.cameraMgr.getSupportedCameras();
Logger.info(TAG, `get cameras: ${JSON.stringify(this.camerasArray)}`);
if (this.camerasArray.length === 0) {
Logger.info(TAG, 'cannot get cameras');
return;
}
let mCamera = this.camerasArray.find((cameraDevice) => cameraDevice.cameraPosition === camera.CameraPosition.CAMERA_POSITION_BACK);
// let sceneModes = this.cameraMgr.getSupportedSceneModes(mCamera);
// Logger.info(TAG, 'SupportedSceneModes: ' + JSON.stringify(sceneModes));
// Logger.info(TAG, 'isTorchSupported: ' + this.cameraMgr.isTorchSupported());
// Logger.info(TAG, 'isTorchModeSupported(camera.TorchMode.ON): ' + this.cameraMgr.isTorchModeSupported(camera.TorchMode.ON));
// Logger.info(TAG, 'isTorchModeSupported(camera.TorchMode.OFF): ' + this.cameraMgr.isTorchModeSupported(camera.TorchMode.OFF));
// Logger.info(TAG, 'isTorchModeSupported(camera.TorchMode.AUTO): ' + this.cameraMgr.isTorchModeSupported(camera.TorchMode.AUTO));
// try {
// this.cameraMgr.setTorchMode(camera.TorchMode.ON);
// } catch(e) {
// Logger.error(TAG, 'setTorchMode error: ' + JSON.stringify(e));
// }
this.cameraInput = this.cameraMgr.createCameraInput(mCamera);
this.cameraInput.open();
Logger.info(TAG, 'createCameraInput');
this.capability = this.cameraMgr.getSupportedOutputCapability(mCamera, camera.SceneMode.NORMAL_PHOTO);
Logger.info(TAG, 'SupportedOutputCapability: ' + JSON.stringify(this.capability.previewProfiles));
let previewProfile = this.capability.previewProfiles[19];
this.previewProfile2 = this.capability?.previewProfiles[19];
this.previewOutput = this.cameraMgr.createPreviewOutput(
previewProfile,
surfaceId
);
let imageReceiveSurfaceId: string = await this.receiver?.getReceivingSurfaceId() ?? "";
Logger.info("imageArrival: imageReceiveSurfaceId: " + imageReceiveSurfaceId);
this.previewOutput2 = this.cameraMgr?.createPreviewOutput(this.previewProfile2, imageReceiveSurfaceId);
Logger.info(TAG, 'createPreviewOutput, previewProfile: ' + JSON.stringify(previewProfile) + 'previewOutput: ' + JSON.stringify(this.previewOutput));
this.capSession = this.cameraMgr.createSession(camera.SceneMode.NORMAL_PHOTO);
Logger.info(TAG, 'createCaptureSession');
this.capSession.beginConfig();
Logger.info(TAG, 'beginConfig');
this.capSession.addInput(this.cameraInput);
this.capSession.addOutput(this.previewOutput);
this.capSession.addOutput(this.previewOutput2);
await this.capSession.commitConfig();
await this.capSession.start();
let FOCUS_MODE_MANUAL = this.capSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_MANUAL);
let FOCUS_MODE_CONTINUOUS_AUTO = this.capSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
let FOCUS_MODE_AUTO = this.capSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_AUTO);
let FOCUS_MODE_LOCKED = this.capSession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_LOCKED);
Logger.info(TAG, 'FOCUS_MODE_MANUAL: ' + FOCUS_MODE_MANUAL + ', FOCUS_MODE_CONTINUOUS_AUTO: ' + FOCUS_MODE_CONTINUOUS_AUTO + ', FOCUS_MODE_AUTO: ' + FOCUS_MODE_AUTO + ', FOCUS_MODE_LOCKED: ' + FOCUS_MODE_LOCKED);
try {
this.capSession.setFocusMode(camera.FocusMode.FOCUS_MODE_AUTO);
Logger.info(TAG, 'setFocusMode success');
} catch (e) {
Logger.info(TAG, 'setFocusMode failed: ' + JSON.stringify(e));
}
let cameraSupportedFrameRatesArray = this.previewOutput.getSupportedFrameRates();
let imageReceiverSupportedFrameRatesArray = this.previewOutput2.getSupportedFrameRates();
Logger.info(TAG, 'cameraSupportedFrameRatesArray: ' + JSON.stringify(cameraSupportedFrameRatesArray) + ', imageReceiverSupportedFrameRatesArray: ' + JSON.stringify(imageReceiverSupportedFrameRatesArray));
try {
// this.previewOutput.setFrameRate(25, 30);
Logger.info(TAG, "setPreviewFrameRate success");
} catch (e) {
Logger.error(TAG, "setPreviewFrameRate failed: " + JSON.stringify(e));
}
Logger.info(TAG, 'captureSession start');
}
setTakePictureHandleCallback(callback): void {
this.takePictureHandle = callback;
}
/**
* 拍照
*/
async takePicture(): Promise<void> {
Logger.info(TAG, 'takePicture');
if (this.currentMode === cameraMode.modeVideo) {
this.currentMode = cameraMode.modePhoto;
}
Logger.info(TAG, `takePicture imageRotation:${this.imageRotation}`);
let photoSettings = {
rotation: this.imageRotation,
quality: camera.QualityLevel.QUALITY_LEVEL_MEDIUM,
location: {
// 位置信息,经纬度
latitude: 12.9698,
longitude: 77.75,
altitude: 1000,
},
mirror: false,
};
Logger.info(TAG, 'takePicture done');
}
/**
* 开始录像
*/
async startVideo(): Promise<void> {
// Logger.info(TAG, 'startVideo begin');
// Logger.info(TAG, 'startVideo 1');
// await this.capSession.stop();
// Logger.info(TAG, 'startVideo 2');
// this.capSession.beginConfig();
// Logger.info(TAG, 'startVideo 3');
// if (this.currentMode === cameraMode.modePhoto) {
// this.currentMode = cameraMode.modeVideo;
// if (this.photoOutPut) {
// this.capSession.removeOutput(this.photoOutPut);
// this.photoOutPut.release();
// }
// } else {
// if (this.videoOutput) {
// try {
// Logger.info(TAG, 'startVideo 4');
// this.capSession.removeOutput(this.videoOutput);
// Logger.info(TAG, 'startVideo 5');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// Logger.info(TAG, `startVideo catch code:${JSON.stringify(e.code)}`);
// Logger.info(TAG, `startVideo catch message:${JSON.stringify(e.message)}`);
// }
// }
// }
// if (this.videoOutput) {
// try {
// Logger.info(TAG, 'startVideo 6');
// this.capSession.removeOutput(this.videoOutput);
// Logger.info(TAG, 'startVideo 7');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// Logger.info(TAG, `startVideo catch code:${JSON.stringify(e.code)}`);
// Logger.info(TAG, `startVideo catch message:${JSON.stringify(e.message)}`);
// }
// try {
// Logger.info(TAG, 'startVideo release 1');
// await this.videoOutput.release();
// Logger.info(TAG, 'startVideo release 2');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// Logger.info(TAG, `startVideo catch code:${JSON.stringify(e.code)}`);
// Logger.info(TAG, `startVideo catch message:${JSON.stringify(e.message)}`);
// }
// }
// Logger.info(TAG, 'startVideo 8');
// this.fileAsset = await this.mediaModel.createAndGetUri(photoAccessHelper.PhotoType.VIDEO);
// Logger.info(TAG, `startVideo fileAsset:${this.fileAsset}`);
// this.fd = await this.mediaModel.getFdPath(this.fileAsset);
// Logger.info(TAG, `startVideo fd:${this.fd}`);
// media.createAVRecorder(async (error, recorder) => {
// Logger.info(TAG, `startVideo into createAVRecorder:${recorder}`);
// if (recorder != null) {
// Logger.info(TAG, `startVideo into recorder:${recorder}`);
// this.avRecorder = recorder;
// Logger.info(TAG, `startVideo createAVRecorder success:${this.avRecorder}`);
// // 当前录像配置
// let currConfig = {
// audioSourceType: 1,
// videoSourceType: this.videoSourceType,
// profile: this.videoProfile,
// url: `fd://${this.fd}`,
// rotation: 0
// };
// Logger.info(TAG, `startVideo into recorder:${recorder}`);
// await this.avRecorder.prepare(currConfig);
// Logger.info(TAG, `startVideo videoConfig:${JSON.stringify(currConfig)}`);
// let videoId = await this.avRecorder.getInputSurface();
// let videoProfile = this.capability.videoProfiles[0];
// Logger.info(TAG, `startVideo capability.videoProfiles[]=: ${JSON.stringify(this.capability.videoProfiles)}`);
// Logger.info(TAG, `startVideo videoProfile:${JSON.stringify(videoProfile)}`);
// this.videoOutput = this.cameraMgr.createVideoOutput(videoProfile, videoId);
// Logger.info(TAG, `startVideo videoOutput:${this.videoOutput}`);
// this.capSession.addOutput(this.videoOutput);
// Logger.info(TAG, 'startVideo addOutput');
// await this.capSession.commitConfig();
// Logger.info(TAG, 'startVideo commitConfig');
// await this.capSession.start();
// Logger.info(TAG, 'startVideo commitConfig capSession');
// await this.videoOutput.start();
// Logger.info(TAG, 'startVideo commitConfig videoOutput');
// try {
// Logger.info(TAG, 'startVideo avRecorder.start 1');
// await this.avRecorder.start();
// Logger.info(TAG, 'startVideo avRecorder.start 2');
// } catch (e) {
// Logger.info(TAG, `startVideo catch e:${JSON.stringify(e)}`);
// }
//
// Logger.info(TAG, 'startVideo end');
//
// } else {
// Logger.info(TAG, `startVideo createAVRecorder fail, error:${error}`);
// }
// });
}
/**
* 停止录像
*/
async stopVideo(): Promise<void> {
Logger.info(TAG, 'stopVideo called');
await this.avRecorder.stop();
await this.avRecorder.release();
await this.videoOutput.stop();
await this.fileAsset.close(this.fd);
}
/**
* 资源释放
*/
async cameraRelease(): Promise<void> {
Logger.info(TAG, 'releaseCamera');
if (this.cameraInput) {
await this.cameraInput.close();
}
if (this.previewOutput) {
await this.previewOutput.release();
}
if (this.videoOutput) {
await this.videoOutput.release();
}
if (this.capSession) {
await this.capSession.release();
}
}
}
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
- 41.
- 42.
- 43.
- 44.
- 45.
- 46.
- 47.
- 48.
- 49.
- 50.
- 51.
- 52.
- 53.
- 54.
- 55.
- 56.
- 57.
- 58.
- 59.
- 60.
- 61.
- 62.
- 63.
- 64.
- 65.
- 66.
- 67.
- 68.
- 69.
- 70.
- 71.
- 72.
- 73.
- 74.
- 75.
- 76.
- 77.
- 78.
- 79.
- 80.
- 81.
- 82.
- 83.
- 84.
- 85.
- 86.
- 87.
- 88.
- 89.
- 90.
- 91.
- 92.
- 93.
- 94.
- 95.
- 96.
- 97.
- 98.
- 99.
- 100.
- 101.
- 102.
- 103.
- 104.
- 105.
- 106.
- 107.
- 108.
- 109.
- 110.
- 111.
- 112.
- 113.
- 114.
- 115.
- 116.
- 117.
- 118.
- 119.
- 120.
- 121.
- 122.
- 123.
- 124.
- 125.
- 126.
- 127.
- 128.
- 129.
- 130.
- 131.
- 132.
- 133.
- 134.
- 135.
- 136.
- 137.
- 138.
- 139.
- 140.
- 141.
- 142.
- 143.
- 144.
- 145.
- 146.
- 147.
- 148.
- 149.
- 150.
- 151.
- 152.
- 153.
- 154.
- 155.
- 156.
- 157.
- 158.
- 159.
- 160.
- 161.
- 162.
- 163.
- 164.
- 165.
- 166.
- 167.
- 168.
- 169.
- 170.
- 171.
- 172.
- 173.
- 174.
- 175.
- 176.
- 177.
- 178.
- 179.
- 180.
- 181.
- 182.
- 183.
- 184.
- 185.
- 186.
- 187.
- 188.
- 189.
- 190.
- 191.
- 192.
- 193.
- 194.
- 195.
- 196.
- 197.
- 198.
- 199.
- 200.
- 201.
- 202.
- 203.
- 204.
- 205.
- 206.
- 207.
- 208.
- 209.
- 210.
- 211.
- 212.
- 213.
- 214.
- 215.
- 216.
- 217.
- 218.
- 219.
- 220.
- 221.
- 222.
- 223.
- 224.
- 225.
- 226.
- 227.
- 228.
- 229.
- 230.
- 231.
- 232.
- 233.
- 234.
- 235.
- 236.
- 237.
- 238.
- 239.
- 240.
- 241.
- 242.
- 243.
- 244.
- 245.
- 246.
- 247.
- 248.
- 249.
- 250.
- 251.
- 252.
- 253.
- 254.
- 255.
- 256.
- 257.
- 258.
- 259.
- 260.
- 261.
- 262.
- 263.
- 264.
- 265.
- 266.
- 267.
- 268.
- 269.
- 270.
- 271.
- 272.
- 273.
- 274.
- 275.
- 276.
- 277.
- 278.
- 279.
- 280.
- 281.
- 282.
- 283.
- 284.
- 285.
- 286.
- 287.
- 288.
- 289.
- 290.
- 291.
- 292.
- 293.
- 294.
- 295.
- 296.
- 297.
- 298.
- 299.
- 300.
- 301.
- 302.
- 303.
- 304.
- 305.
- 306.
- 307.
- 308.
- 309.
- 310.
- 311.
- 312.
- 313.
- 314.
- 315.
- 316.
- 317.
- 318.
- 319.
- 320.
- 321.
- 322.
- 323.
- 324.
- 325.
- 326.
- 327.
- 328.
- 329.
- 330.
- 331.
- 332.
- 333.
- 334.
- 335.
- 336.
- 337.
- 338.
- 339.
- 340.
- 341.
- 342.
- 343.
- 344.
- 345.
- 346.
- 347.
- 348.
- 349.
- 350.
- 351.
- 352.
- 353.
- 354.
- 355.
- 356.
- 357.
- 358.
- 359.
- 360.
- 361.
- 362.
- 363.
- 364.
- 365.
- 366.
- 367.
- 368.
- 369.
- 370.
- 371.
- 372.
- 373.
- 374.
- 375.
- 376.
- 377.
- 378.
- 379.
- 380.
- 381.
- 382.
- 383.
- 384.
- 385.
- 386.
- 387.
- 388.
- 389.
- 390.
- 391.
- 392.
- 393.
- 394.
- 395.
- 396.
- 397.
- 398.
- 399.
- 400.
- 401.
- 402.
- 403.
- 404.
- 405.
- 406.
- 407.
- 408.
- 409.
- 410.
- 411.
- 412.
- 413.
- 414.
- 415.
- 416.
- 417.
- 418.
- 419.
- 420.
- 421.
- 422.
- 423.
- 424.
- 425.
- 426.
- 427.
- 428.
- 429.
- 430.
- 431.
- 432.
- 433.
- 434.
- 435.
- 436.
- 437.
- 438.
- 439.
- 440.
- 441.
- 442.
- 443.
- 444.
- 445.
- 446.
- 447.
- 448.
- 449.
- 450.
- 451.
- 452.
- 453.
- 454.
- 455.
- 456.
- 457.
- 458.
- 459.
- 460.
- 461.
- 462.
- 463.
- 464.
- 465.
- 466.
- 467.
- 468.
- 469.
- 470.
- 471.
- 472.
- 473.
- 474.
- 475.
- 476.
- 477.
- 478.
- 479.
- 480.
- 481.
- 482.
- 483.
- 484.
- 485.
- 486.
- 487.
- 488.
- 489.
- 490.
- 491.
- 492.
- 493.
- 494.
- 495.
- 496.
- 497.
- 498.
- 499.
- 500.
- 501.
- 502.
- 503.
- 504.
- 505.
- 506.
- 507.
- 508.
- 509.
- 510.
- 511.
- 512.
- 513.
- 514.
- 515.
- 516.
- 517.
- 518.
- 519.
- 520.
- 521.
- 522.
- 523.
- 524.
- 525.
- 526.
- 527.
- 528.
- 529.
- 530.
- 531.
- 532.
- 533.
- 534.
- 535.
- 536.
- 537.
- 538.
- 539.
- 540.
- 541.
- 542.
- 543.
- 544.
- 545.
- 546.
- 547.
- 548.
- 549.
- 550.
- 551.
- 552.
- 553.
- 554.
- 555.
- 556.
- 557.
- 558.
- 559.
- 560.
- 561.
- 562.
- 563.
- 564.
- 565.
- 566.
- 567.
- 568.
- 569.
- 570.
- 571.
- 572.
- 573.
- 574.
- 575.
- 576.
- 577.
- 578.
- 579.
- 580.
UIUtils.ets
import Logger from './Logger';
const TAG: string = "UIUtilsManagerTAG";
class UIUtilsManager {
private static _instance: UIUtilsManager;
private constructor() {
}
static getInstance(): UIUtilsManager {
if (!UIUtilsManager._instance) {
UIUtilsManager._instance = new UIUtilsManager();
}
return UIUtilsManager._instance;
}
extractComponentSizeByID(id: string): [number, number] {
let re: ESObject = JSON.parse(getInspectorByKey(id));
let rect: string = re.$rect;
Logger.info(TAG, `result: ${JSON.stringify(re.$rect)}`);
const regex = new RegExp(/^\[(\d+(\.\d+)?),\s*(\d+(\.\d+)?)]\,\[(\d+(\.\d+)?),\s*(\d+(\.\d+)?)]$/);
const match = rect.match(regex);
if (match) {
const x1 = parseFloat(match[5]);
const y1 = parseFloat(match[7]);
Logger.info(TAG, `extractComponentSizeByID success, id: ${id}, x1: ${x1}, y1: ${y1}`);
return [x1, y1];
} else {
Logger.error(TAG, `extractComponentSizeByID failed, id: ${id}`);
return [0, 0];
}
}
}
export let uiUtilsManager = UIUtilsManager.getInstance();
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
- 11.
- 12.
- 13.
- 14.
- 15.
- 16.
- 17.
- 18.
- 19.
- 20.
- 21.
- 22.
- 23.
- 24.
- 25.
- 26.
- 27.
- 28.
- 29.
- 30.
- 31.
- 32.
- 33.
- 34.
- 35.
- 36.
- 37.
- 38.
- 39.
- 40.
©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
赞
收藏
回复
分享
微博
QQ
微信
举报
举报
1
微信扫码分享
删除帖子
删除 取消
相关推荐
相机的预览画面旋转90怎么处理,即使拍照角度正常,但是预览还是的旋转才正常啊