HarmonyOS鸿蒙Next中自定义相机横向拍照,摄像头方向差了90度

HarmonyOS鸿蒙Next中自定义相机横向拍照,摄像头方向差了90度 在开发自定义相机拍照功能时,因为需要横向拍照,所以将界面横向设置之后,发现摄像头看到的画面是差了90度,请问要怎么设置这个摄像头方向?

3 回复

可参考

const TAG = '[SystemCameraDemo]';

@Entry
@Component
struct Index {
  @State path: string = '';
  @State isVideo: boolean = false;
  private context = this.getContext(this) as common.UIAbilityContext;

  build() {
    Column({ space: 20 }) {
      Button('拉起系统相机拍照--startAbility方式')
        .width(300)
        .height(50)
        .onClick(async () => {
          this.startAbility('ohos.want.action.imageCapture', 'com.huawei.flexlaout.myapplication');
        })

      Button('拉起系统相机录像--startAbility方式')
        .width(300)
        .height(50)
        .onClick(async () => {
          this.startAbility('ohos.want.action.videoCapture', 'com.huawei.flexlaout.myapplication');
        })

      Button('拉起系统相机拍照--cameraPicker方式')
        .width(300)
        .height(50)
        .onClick(async () => {
          this.cameraPicker(cameraPicker.PickerMediaType.PHOTO);
        })

      Button('拉起系统相机录像--cameraPicker方式')
        .width(300)
        .height(50)
        .onClick(async () => {
          this.cameraPicker(cameraPicker.PickerMediaType.VIDEO);
        })

      if (this.isVideo && this.path) {
        Video({ src: this.path })
          .objectFit(ImageFit.Contain)
          .width('100%')
          .height(300)
      }
      if (!this.isVideo && this.path) {
        Image(this.path)
          .objectFit(ImageFit.Contain)
          .width('100%')
          .height(300)
      }
    }
    .width('100%')
  }

  async cameraPicker(type: cameraPicker.PickerMediaType) {
    try {
      let pickerProfile: cameraPicker.PickerProfile = {
        // 相机的位置  后置摄像头
        cameraPosition: camera.CameraPosition.CAMERA_POSITION_BACK,
        //saveUri 保存配置信息的uri
        //videoDuration 录制的最大时长
      };
      cameraPicker.pick(getContext(this), [type], pickerProfile)
        .then((result: cameraPicker.PickerResult) => {
          if (result.resultCode != 0) {
            // 处理业务逻辑错误
            console.error(TAG, `cameraPicker.pick failed, result is ${JSON.stringify(result)}`);
            promptAction.showToast({ message: '拍摄失败' })
            return;
          }
          //若saveUri为空,resultUri为公共媒体路径。若saveUri不为空且具备写权限,resultUri与saveUri相同。若saveUri不为空且不具备写权限,则无法获取到resultUri
          let uri: string = result.resultUri;
          // 执行正常业务
          console.info(TAG, `Succeeded in cameraPicker.pick. Data is ${JSON.stringify(result)}, uri is ${uri}`);
          if (uri) {
            // 保存到本地
            this.save2Local(uri);
          } else {
            promptAction.showToast({ message: '拍摄失败' })
          }
        })
    } catch (error) {
      let err = error as BusinessError;
      console.error(TAG, `the pick call failed. error code: ${err.code}`);
      promptAction.showToast({ message: '拍摄失败' })
    }
  }

  startAbility(action: string, bundleName: string) {
    let want: Want = {
      action: action,
      parameters: {
        // 拍照完成后返回的应用BundleName
        callBundleName: bundleName,
        supportMultiMode: false
      }
    };

    try {
      this.context.startAbilityForResult(want, (err: BusinessError, result: common.AbilityResult) => {
        if (err.code) {
          // 处理业务逻辑错误
          console.error(TAG, `startAbilityForResult failed, code is ${err.code}, message is ${err.message}`);
          return;
        }
        let uri: string = result?.want?.parameters?.resourceUri as string;
        // 执行正常业务
        console.info(TAG, `Succeeded in starting ability for result. Data is ${JSON.stringify(result)}, uri is ${uri}`);
        if (uri) {
          // 保存到本地
          this.save2Local(uri);
        } else {
          promptAction.showToast({ message: '拍摄失败' })
        }
      });
    } catch (err) {
      let error = err as BusinessError;
      console.error(TAG, `startAbilityForResult failed, err is ${JSON.stringify(error)}`);
      promptAction.showToast({ message: '拍摄失败' })
    }
  }

  save2Local(uri: string) {
    try {
      let file = fileIo.openSync(uri, fileIo.OpenMode.READ_ONLY);
      let prefix = uri.substring(uri.lastIndexOf('.') + 1);
      let tempFileName = getContext(this).filesDir + '/' + new Date().getTime() + '.' + prefix;
      let tempFile = fileIo.openSync(tempFileName, fileIo.OpenMode.READ_WRITE | fileIo.OpenMode.CREATE);
      fileIo.copyFileSync(file.fd, tempFile.fd);
      this.path = fileUri.getUriFromPath(tempFileName);
      this.isVideo = (prefix == 'mp4' || prefix == 'MP4');
      console.info(TAG, `resolve2Sandbox successful.`);
      promptAction.showToast({ message: '拍摄成功' })
    } catch (err) {
      let error = err as BusinessError;
      console.error(TAG, `resolve2Sandbox failed, err is ${JSON.stringify(error)}`);
    }
  }
}

更多关于HarmonyOS鸿蒙Next中自定义相机横向拍照,摄像头方向差了90度的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html


在HarmonyOS鸿蒙Next中,自定义相机横向拍照时摄像头方向差了90度,通常是由于设备方向与相机预览方向不一致导致的。鸿蒙系统提供了CameraAbilityPreviewCallback等API,可以通过设置相机参数来调整预览方向。可以通过setDisplayOrientation方法设置相机预览方向,确保与设备方向一致。此外,可以使用OrientationEventListener监听设备方向变化,动态调整相机预览方向,确保拍照时方向正确。

在HarmonyOS鸿蒙Next中,如果自定义相机横向拍照时摄像头方向差了90度,通常是因为图像传感器的默认方向与设备物理方向不一致。可以通过设置CameraConfig中的targetRotation属性来调整图像方向,使其与设备物理方向匹配。例如:

CameraConfig cameraConfig = new CameraConfig.Builder()
    .setTargetRotation(Surface.ROTATION_90) // 根据设备方向调整
    .build();
cameraDevice.configure(cameraConfig);

确保在构建相机配置时正确设置targetRotation,并监听设备方向变化,动态调整该参数。

回到顶部