讨论广场 问答详情
有些照片显示会旋转 90 度,需要根据 EXIF 方向修正。请问在HarmonyOS开发中,要如何读取 EXIF 并自动调整?
晚风依旧似温柔 2025-09-12 11:14:21
154 评论 分享
鸿蒙问答专区

有些照片显示会旋转 90 度,需要根据 EXIF 方向修正。请问在HarmonyOS开发中,要如何读取 EXIF 并自动调整?
相关代码:

```ts
import image from '@ohos.multimedia.image';
const ori = image.getExifOrientation(path);
if (ori === 6) rotate90(img);
```


 

154 评论 分享
写回答
全部评论(1)
1 楼

1. 导入模块并获取图片源
首先,你需要导入相关的模块,并获取图片的 ImageSource。这可以通过文件描述符(fd)、文件路径或 URI 等方式实现。
import image from '@ohos.multimedia.image';
import { BusinessError } from '@ohos.base';

// 假设你有一个图片的 URI 或路径
let imageUri: string = '...'; // 你的图片路径或 URI

// 方式1: 通过文件路径创建 ImageSource (需要合适的上下文和权限)
const imageSource: image.ImageSource = image.createImageSource(imageUri);

// 方式2: 如果你有文件描述符 (fd),也可以使用
// const imageSource = image.createImageSource(fd);
2. 读取 EXIF 中的 Orientation 属性
使用 getImageProperty 方法来读取特定的 EXIF 属性。注意,根据1的信息,HarmonyOS 的 getImageProperty 接口在读取 'Orientation' 参数时,可能会获取到 Thumbnail.Orientation 而非 Image.Orientation,这点需要留意。


async function getExifOrientation(imageSource: image.ImageSource): Promise<number> {
  try {
    // 读取 Orientation 属性。注意返回值是 string 类型,需要转换为 number。
    const orientationString: string = await imageSource.getImageProperty('Orientation');
    const orientation: number = parseInt(orientationString, 10);
    
    // 处理可能的 NaN
    if (isNaN(orientation)) {
      console.warn('Failed to parse Orientation property, defaulting to 1.');
      return 1; // 默认值,表示正常方向
    }
    console.info(`Succeeded in getting image orientation: ${orientation}`);
    return orientation;
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to get image orientation. Code: ${err.code}, message: ${err.message}`);
    // 如果读取失败(例如无 EXIF 信息),也返回默认值 1
    return 1;
  }
}


3. 根据 Orientation 值处理图片
获取到 Orientation 值后,需要根据其含义对图片进行相应的旋转或镜像处理。标准的 EXIF Orientation 标签及其含义如下表所示:

Orientation 值    含义    需要进行的调整
1    正常方向(0°)    无
2    水平翻转(镜像)    水平翻转
3    旋转 180°    旋转 180°
4    垂直翻转    垂直翻转
5    水平翻转并逆时针旋转 90°    水平翻转并旋转 270°(或逆时针 90°)
6 (常见)    逆时针旋转 90°
(你提到的 ori === 6 就是这种情况1)    旋转 90°
7    水平翻转并逆时针旋转 270°    水平翻转并旋转 90°
8    逆时针旋转 270°    旋转 270°(或逆时针 270°)

// 处理图片方向的核心函数
async function correctImageOrientation(originalPixelMap: image.PixelMap, orientation: number): Promise<image.PixelMap> {
  let processedPixelMap: image.PixelMap = originalPixelMap;

  try {
    switch (orientation) {
      case 2:
        // 水平翻转
        await processedPixelMap.flip(true); // 水平翻转
        break;
      case 3:
        // 旋转 180°
        await processedPixelMap.rotate(180);
        break;
      case 4:
        // 垂直翻转
        await processedPixelMap.flip(false); // 垂直翻转
        break;
      case 5:
        // 水平翻转并逆时针旋转 90° -> 水平翻转并旋转 270°
        await processedPixelMap.flip(true);
        processedPixelMap = await processedPixelMap.rotate(270);
        break;
      case 6:
        // 逆时针旋转 90° -> 需要旋转 90° (你遇到的问题)
        await processedPixelMap.rotate(90);
        break;
      case 7:
        // 水平翻转并逆时针旋转 270° -> 水平翻转并旋转 90°
        await processedPixelMap.flip(true);
        processedPixelMap = await processedPixelMap.rotate(90);
        break;
      case 8:
        // 逆时针旋转 270° -> 旋转 270°
        await processedPixelMap.rotate(270);
        break;
      case 1:
      default:
        // 情况 1 或未知情况,不做任何处理
        break;
    }
  } catch (error) {
    const err: BusinessError = error as BusinessError;
    console.error(`Failed to correct image orientation. Code: ${err.code}, message: ${err.message}`);
  }

  return processedPixelMap;
}

2025-09-12 11:28:54