HarmonyOS鸿蒙Next中Camera Kit:使用相机服务预览时,前置摄像头清晰,后置模糊如何解决
HarmonyOS鸿蒙Next中Camera Kit:使用相机服务预览时,前置摄像头清晰,后置模糊如何解决 使用相机服务预览时,前置摄像头清晰,后置模糊如何解决
3 回复
楼主你好,可以尝试如下代码
import camera from '@ohos.multimedia.camera';
import { BusinessError } from '@ohos.base';
import image from '@ohos.multimedia.image';
import abilityAccessCtrl, { PermissionRequestResult, Permissions } from '@ohos.abilityAccessCtrl';
import bundleManager from '@ohos.bundle.bundleManager';
import { GlobalContext } from '../utils/GlobalContext';
import Logger from '../utils/Logger';
import common from '@ohos.app.ability.common';
let context = getContext() as common.UIAbilityContext;
let TAG: string = "Index";
let camerasession: camera.CaptureSession
let cameraInput: camera.CameraInput
let photoOutPut: camera.PhotoOutput
let previewOutput: camera.PreviewOutput;
let previewOutput2: camera.PreviewOutput;
let captureSession: camera.CaptureSession;
let cameraWidth = 1920;
let cameraHeight = 1080;
let mXComponentController: XComponentController = new XComponentController;
let surfaceId: string = '';
let pixma: PixelMap | undefined = undefined
let ca: Number = 0
private receiver: image.ImageReceiver = this.createImageReceiver();
await grantPermission().then(res => {
console.info(TAG, `权限申请成功 ${JSON.stringify(res)}`);
if (res) {
//预览和拍照
createPhotoAndPreview(surfaceId, receiver, ca);
}
})
@Component
@Entry
struct XComponentPage {
build() {
Column() {
XComponent({
id: '',
type: 'surface',
libraryname: '',
controller: this.mXComponentController
})
.onLoad(async () => {
// 设置Surface宽高(1920*1080),预览尺寸设置参考前面 previewProfilesArray 获取的当前设备所支持的预览分辨率大小去设置
// 预览流与录像输出流的分辨率的宽高比要保持一致
// this.mXComponentController.setXComponentSurfaceSize({ surfaceWidth: cameraWidth, surfaceHeight: cameraHeight });
// 获取Surface ID
this.surfaceId = this.mXComponentController.getXComponentSurfaceId();
})
.width('1080px')
.height('1920px')
Button() {
Text("拍照")
.fontColor(Color.Black)
.alignSelf(ItemAlign.Center)
.onClick(() => {
let settings: camera.PhotoCaptureSetting = {
quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高
rotation: camera.ImageRotation.ROTATION_0, // 设置图片旋转角度0
mirror: false // 设置镜像使能开关(默认关)
};
photoOutPut.capture(settings, (err: BusinessError) => {
if (err) {
console.error(`Failed to capture the photo. error: ${JSON.stringify(err)}`);
return;
}
console.info('Callback invoked to indicate the photo capture request success.');
});
})
}
.width(100)
.height(100)
Button('摄像头_front')
.size({ width: 150, height: 34 })
.margin({ left: 10 })
.onClick(() => {
ca = 1
removeSession(captureSession, cameraInput, previewOutput, photoOutPut)
createPhotoAndPreview(surfaceId, receiver, ca)
// this.cameraController.setDevicePosition(DevicePosition.front);
})
Button('摄像头_back')
.size({ width: 150, height: 34 })
.margin({ left: 10 })
.onClick(() => {
ca = 0
removeSession(captureSession, cameraInput, previewOutput, photoOutPut)
createPhotoAndPreview(surfaceId, receiver, ca)
// this.cameraController.setDevicePosition(DevicePosition.back);
})
}
}
configuringSession(): void {
// 判断设备是否支持闪光灯
let flashStatus: boolean = false;
try {
flashStatus = camerasession.hasFlash();
} catch (error) {
let err = error as BusinessError;
console.error('Failed to hasFlash. errorCode = ' + err.code);
}
console.info('Promise returned with the flash light support status:' + flashStatus);
if (flashStatus) {
// 判断是否支持自动闪光灯模式
let flashModeStatus: boolean = false;
try {
let status: boolean = camerasession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO);
flashModeStatus = status;
} catch (error) {
let err = error as BusinessError;
console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code);
}
if (flashModeStatus) {
// 设置自动闪光灯模式
try {
camerasession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO);
} catch (error) {
let err = error as BusinessError;
console.error('Failed to set the flash mode. errorCode = ' + err.code);
}
}
}
// 判断是否支持连续自动变焦模式
let focusModeStatus: boolean = false;
try {
let status: boolean = camerasession.isFocusModeSupported(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
focusModeStatus = status;
} catch (error) {
let err = error as BusinessError;
console.error('Failed to check whether the focus mode is supported. errorCode = ' + err.code);
}
if (focusModeStatus) {
// 设置连续自动变焦模式
try {
camerasession.setFocusMode(camera.FocusMode.FOCUS_MODE_CONTINUOUS_AUTO);
} catch (error) {
let err = error as BusinessError;
console.error('Failed to set the focus mode. errorCode = ' + err.code);
}
}
// 获取相机支持的可变焦距比范围
let zoomRatioRange: Array<number> = [];
try {
zoomRatioRange = camerasession.getZoomRatioRange();
} catch (error) {
let err = error as BusinessError;
console.error('Failed to get the zoom ratio range. errorCode = ' + err.code);
}
if (zoomRatioRange.length <= 0) {
return;
}
// 设置可变焦距比
try {
camerasession.setZoomRatio(zoomRatioRange[0]);
} catch (error) {
let err = error as BusinessError;
console.error('Failed to set the zoom ratio value. errorCode = ' + err.code);
}
}
async getImageReceiverSurfaceId(): Promise<string | undefined> {
let photoSurfaceId: string | undefined = undefined;
let receiver: image.ImageReceiver = image.createImageReceiver(640, 480, 4, 8);
console.info('before ImageReceiver check');
if (receiver !== undefined) {
console.info('ImageReceiver is ok');
photoSurfaceId = await receiver.getReceivingSurfaceId();
console.info(`ImageReceived id: ${JSON.stringify(photoSurfaceId)}`);
} else {
console.info('ImageReceiver is not ok');
}
return photoSurfaceId;
}
createImageReceiver(): image.ImageReceiver {
let receiver: image.ImageReceiver = image.createImageReceiver(cameraWidth, cameraHeight, 4, 8);
console.info('imageArrival11');
receiver.on("imageArrival", async (e, data) => {
console.info('imageArrival');
let imageData = await receiver.readNextImage()
let imgComponent = await imageData.getComponent(image.ComponentType.JPEG)
image.createImageSource(imgComponent.byteBuffer)
.createPixelMap().then((px) => {
this.pixma = px
})
})
return receiver;
}
capture(photoOutput: camera.PhotoOutput, captureLocation?: camera.Location,): void {
let settings: camera.PhotoCaptureSetting = {
quality: camera.QualityLevel.QUALITY_LEVEL_HIGH, // 设置图片质量高
rotation: camera.ImageRotation.ROTATION_0, // 设置图片旋转角度0
location: captureLocation, // 设置图片地理位置
mirror: false // 设置镜像使能开关(默认关)
};
photoOutput.capture(settings, (err: BusinessError) => {
if (err) {
console.error(`Failed to capture the photo. error: ${JSON.stringify(err)}`);
return;
}
console.info('Callback invoked to indicate the photo capture request success.');
});
}
async getSupportedOutputCapability(cameraDevice: camera.CameraDevice,
cameraManager: camera.CameraManager): Promise<camera.CameraOutputCapability | undefined> {
// 创建相机输入流
let cameraInput: camera.CameraInput | undefined = undefined;
try {
cameraInput = cameraManager.createCameraInput(cameraDevice);
} catch (error) {
let err = error as BusinessError;
console.error('Failed to createCameraInput errorCode = ' + err.code);
}
if (cameraInput === undefined) {
return undefined;
}
// 监听cameraInput错误信息
cameraInput.on('error', cameraDevice, (error: BusinessError) => {
console.info(`Camera input error code: ${error.code}`);
});
cameraInput = cameraInput
// 打开相机
await cameraInput.open();
// 获取相机设备支持的输出流能力
let cameraOutputCapability: camera.CameraOutputCapability =
cameraManager.getSupportedOutputCapability(cameraDevice);
if (!cameraOutputCapability) {
console.error("cameraManager.getSupportedOutputCapability error");
return undefined;
}
console.info("outputCapability: " + JSON.stringify(cameraOutputCapability));
return cameraOutputCapability;
}
}
async function grantPermission(): Promise<boolean> {
const PERMISSIONS: Array<Permissions> = [
'ohos.permission.CAMERA',
];
try {
// 获取应用程序的accessTokenID
let bundleInfo: bundleManager.BundleInfo =
await bundleManager.getBundleInfoForSelf(
bundleManager.BundleFlag.GET_BUNDLE_INFO_WITH_APPLICATION
);
let appInfo: bundleManager.ApplicationInfo = bundleInfo.appInfo;
let tokenId = appInfo.accessTokenId;
let atManager = abilityAccessCtrl.createAtManager();
let pems: Array<Permissions> = [];
for (let i = 0; i < PERMISSIONS.length; i++) {
let state = await atManager.checkAccessToken(tokenId, PERMISSIONS[i]);
console.info(TAG, `grantPermission checkAccessToken ${PERMISSIONS[i]} + : ${JSON.stringify(state)}`);
if (state !== abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
pems.push(PERMISSIONS[i]);
}
}
if (pems.length > 0) {
console.info(TAG, 'grantPermission requestPermissionsFromUser :' + JSON.stringify(pems));
let result = await atManager.requestPermissionsFromUser(GlobalContext.get().getCameraAbilityContext(), pems);
let grantStatus: Array<number> = result.authResults;
let length: number = grantStatus.length;
for (let i = 0; i < length; i++) {
// console.info(TAG, `grantPermission requestPermissionsFromUser ${result.permissions[i]} + : ${grantStatus[i]}`);
if (grantStatus[i] === 0) {
// 用户授权,可以继续访问目标操作
} else {
// 用户拒绝授权,提示用户必须授权才能访问当前页面的功能
console.log(TAG + 'grantPermission fail ');
return false;
}
}
}
// 授权成功
console.info(TAG, 'grantPermission success ');
return true;
} catch (e) {
console.info(TAG, 'grantPermission fail ');
return false;
}
}
//预览流和拍照流
async function createPhotoAndPreview(XComponentSurfaceId: string, receiver: image.ImageReceiver,
ca: Number): Promise<void> {
releaseCamera();
let cameraManager = getCameraManager();
let camerasDevices: Array<camera.CameraDevice> = getCameraDevices(cameraManager); // 获取支持的相机设备对象
let profiles: camera.CameraOutputCapability
if (ca == 0) {
// 获取profile对象
profiles = cameraManager.getSupportedOutputCapability(camerasDevices[0]); // 获取对应相机设备profiles
} else {
profiles = cameraManager.getSupportedOutputCapability(camerasDevices[1]); // 获取对应相机设备profiles
}
let previewProfiles: Array<camera.Profile> = profiles.previewProfiles
Logger.debug("createDualChannelPreview-- previewProfiles:" + previewProfiles.length)
// 预览流
let index_1080_1920: number = 0
previewProfiles.forEach((item, index) => {
if (item.size.width == 1920 && item.size.height == 1080 && item.format == 1003) {
index_1080_1920 = index;
console.log('1111111111111111111:' + index_1080_1920)
}
})
let previewProfilesObj: camera.Profile = previewProfiles[index_1080_1920];
console.log('预览配置列表:' + JSON.stringify(previewProfiles))
console.log('预览配置个数num=' + JSON.stringify(previewProfiles.length))
// 拍照流
let previewProfilesObj2: camera.Profile = profiles.photoProfiles[0];
// 创建 预览流 输出对象
previewOutput = cameraManager.createPreviewOutput(previewProfilesObj, XComponentSurfaceId);
// 创建 拍照流 输出对象
let imageReceiverSurfaceId: string = await receiver.getReceivingSurfaceId();
photoOutPut = cameraManager.createPhotoOutput(previewProfilesObj2, imageReceiverSurfaceId);
// 创建cameraInput对象
if (ca == 0) {
cameraInput = cameraManager.createCameraInput(camerasDevices[0]);
} else {
cameraInput = cameraManager.createCameraInput(camerasDevices[1]);
}
// 打开相机
await cameraInput.open();
// 会话流程
captureSession = cameraManager.createCaptureSession();
// 开始配置会话
captureSession.beginConfig();
// 把CameraInput加入到会话
captureSession.addInput(cameraInput);
// 把 预览流 加入到会话
captureSession.addOutput(previewOutput)
// 把 拍照流 加入到会话
captureSession.addOutput(photoOutPut);
// 提交配置信息
await captureSession.commitConfig();
// 会话开始
await captureSession.start();
// 判断设备是否支持闪光灯
let flashStatus: boolean = false;
try {
flashStatus = camerasession.hasFlash();
} catch (error) {
let err = error as BusinessError;
console.error('Failed to hasFlash. errorCode = ' + err.code);
}
console.info('Promise returned with the flash light support status:' + flashStatus);
if (flashStatus) {
// 判断是否支持自动闪光灯模式
let flashModeStatus: boolean = false;
try {
let status: boolean = camerasession.isFlashModeSupported(camera.FlashMode.FLASH_MODE_AUTO);
flashModeStatus = status;
} catch (error) {
let err = error as BusinessError;
console.error('Failed to check whether the flash mode is supported. errorCode = ' + err.code);
}
if (flashModeStatus) {
// 设置自动闪光灯模式
try {
camerasession.setFlashMode(camera.FlashMode.FLASH_MODE_AUTO);
} catch (error) {
let err = error as BusinessError;
console.error('Failed to set the flash mode. errorCode = ' + err.code);
}
}
}
}
async function releaseCamera() {
if (cameraInput) {
cameraInput.close()
}
if (previewOutput) {
previewOutput.release()
}
if (previewOutput2) {
previewOutput2.release()
}
if (captureSession) {
captureSession.release()
}
}
function onPreviewOutputFrameStart
(
previewOutput:
camera.PreviewOutput
):
void {
previewOutput.on('frameStart', () => {
console.info('Preview frame started');
});
}
function getCameraManager(): camera.CameraManager {
// return camera.getCameraManager(GlobalContext.get().getCameraAbilityContext());
return camera.getCameraManager(context);
}
function onPreviewOutputFrameEnd(previewOutput: camera.PreviewOutput): void {
previewOutput.on('frameEnd', () => {
console.info('Preview frame ended');
});
}
function onPreviewOutputError(previewOutput: camera.PreviewOutput): void {
previewOutput.on('error', (previewOutputError: BusinessError) => {
console.info(`Preview output error code: ${previewOutputError.code}`);
});
}
function onPhotoOutputEnd(photoOutput: camera.PhotoOutput) {
photoOutput.on('captureEnd', (err, data) => {
data.captureId
})
}
function getCameraDevices(cameraManager: camera.CameraManager): Array<camera.CameraDevice> {
let cameraArray: Array<camera.CameraDevice> = cameraManager.getSupportedCameras();
if (cameraArray != undefined && cameraArray.length <= 0) {
console.error("cameraManager.getSupportedCameras error");
return [];
}
for (let index = 0; index < cameraArray.length; index++) {
console.info('cameraId : ' + cameraArray[index].cameraId); // 获取相机ID
console.info('cameraPosition : ' + cameraArray[index].cameraPosition); // 获取相机位置
console.info('cameraType : ' + cameraArray[index].cameraType); // 获取相机类型
console.info('connectionType : ' + cameraArray[index].connectionType); // 获取相机连接类型
}
return cameraArray;
}
function getCaptureSession(cameraManager: camera.CameraManager): camera.CaptureSession {
let captureSession = cameraManager.createCaptureSession();
return captureSession;
}
function beginConfig(captureSession: camera.CaptureSession): void {
try {
captureSession.beginConfig();
console.log("======> success")
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to beginConfig. error: ${JSON.stringify(err)}`);
}
}
async function startSession(captureSession: camera.CaptureSession, cameraInput: camera.CameraInput,
previewOutput: camera.PreviewOutput,
photoOutput: camera.PhotoOutput): Promise<void> {
try {
captureSession.addInput(cameraInput);
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to addInput. error: ${JSON.stringify(err)}`);
}
try {
captureSession.addOutput(previewOutput);
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to add previewOutput. error: ${JSON.stringify(err)}`);
}
try {
captureSession.addOutput(photoOutput);
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to add photoOutput. error: ${JSON.stringify(err)}`);
}
try {
await captureSession.commitConfig();
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to commitConfig. error: ${JSON.stringify(err)}`);
}
try {
await captureSession.start()
} catch (error) {
let err = error as BusinessError;
console.error(`Failed to start. error: ${JSON.stringify(err)}`);
}
}
async function removeSession(captureSession: camera.CaptureSession, cameraInput: camera.CameraInput,
previewOutput: camera.PreviewOutput, photoOutput: camera.PhotoOutput) {
captureSession.removeInput(cameraInput)
captureSession.removeOutput(previewOutput)
captureSession.removeOutput(photoOutput)
}
更多关于HarmonyOS鸿蒙Next中Camera Kit:使用相机服务预览时,前置摄像头清晰,后置模糊如何解决的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS鸿蒙Next中,使用Camera Kit进行相机服务预览时,如果前置摄像头清晰而后置摄像头模糊,可能的原因包括:
- 摄像头硬件问题:后置摄像头可能存在硬件故障或镜头脏污,影响成像质量。
- 软件配置问题:后置摄像头的参数配置可能不正确,如分辨率、对焦模式等未优化。
- 权限设置问题:应用可能未正确获取后置摄像头的权限,导致无法完全启用其功能。
- API调用问题:在使用Camera Kit的API时,可能未正确处理后置摄像头的初始化或配置。
解决步骤:
- 检查硬件:确保后置摄像头无物理损伤或脏污。
- 验证配置:检查Camera Kit中后置摄像头的配置参数,确保与设备规格匹配。
- 确认权限:确保应用已正确申请并获取了后置摄像头的使用权限。
- 调试API:审查Camera Kit的API调用,确保后置摄像头的初始化和配置正确无误。
通过上述步骤,可以定位并解决后置摄像头模糊的问题。
在HarmonyOS鸿蒙Next中使用Camera Kit进行预览时,如果前置摄像头清晰而后置摄像头模糊,可以按照以下步骤进行排查和解决:
- 检查镜头清洁:确保后置摄像头镜头没有污渍或遮挡。
- 对焦设置:确认后置摄像头的对焦模式是否正确,尝试使用自动对焦(AF)或手动对焦(MF)进行调整。
- 分辨率配置:检查后置摄像头的分辨率设置,确保其与前置摄像头一致或适当。
- 硬件问题:如果软件调整无效,可能是后置摄像头硬件故障,建议联系售后检测。
通过以上步骤,通常可以解决后置摄像头模糊的问题。