You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

React Native如何获取设备中JPG图片的方向?

React Native 获取JPG图片实际方向(支持Android/iOS)

React Native 的 Image.getSize() 仅返回图片的原始像素宽高,不会解析JPG文件的EXIF Orientation标签,导致竖拍照片的宽高与实际显示方向不符。以下是两种跨平台解决方案:

方案一:使用第三方EXIF解析库

推荐使用 react-native-exif 直接读取图片的EXIF元数据,快速获取Orientation信息。

步骤:

  1. 安装依赖
npm install react-native-exif --save
# 或使用yarn
yarn add react-native-exif
  1. 读取图片方向
import Exif from 'react-native-exif';

async function getImageOrientation(imagePath) {
  try {
    const exifData = await Exif.getExif(imagePath);
    // Orientation值范围1-8,对应不同旋转/翻转方向,默认返回1(正常方向)
    return exifData.Orientation || 1;
  } catch (error) {
    console.error('读取EXIF失败:', error);
    return 1;
  }
}
  1. 根据Orientation修正实际宽高
    结合 Image.getSize() 的结果,调整为符合实际显示的宽高:
import { Image } from 'react-native';

async function getActualImageSize(imagePath) {
  const [rawSize, orientation] = await Promise.all([
    new Promise((resolve) => {
      Image.getSize(imagePath, (width, height) => resolve({ width, height }));
    }),
    getImageOrientation(imagePath)
  ]);

  let actualWidth = rawSize.width;
  let actualHeight = rawSize.height;

  // 旋转90/270度时,宽高互换
  if (orientation >= 5 && orientation <= 8) {
    [actualWidth, actualHeight] = [actualHeight, actualWidth];
  }

  return { width: actualWidth, height: actualHeight, orientation };
}

方案二:自定义原生模块(无第三方依赖)

若不想引入外部库,可编写原生代码直接读取EXIF的Orientation标签。

iOS端原生代码

// RNImageOrientationManager.h
#import <React/RCTBridgeModule.h>

@interface RNImageOrientationManager : NSObject <RCTBridgeModule>
@end

// RNImageOrientationManager.m
#import "RNImageOrientationManager.h"
#import <ImageIO/ImageIO.h>

@implementation RNImageOrientationManager

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(getOrientation:(NSString *)imagePath resolve:(RCTPromiseResolveBlock)resolve reject:(RCTPromiseRejectBlock)reject) {
  NSURL *url = [NSURL fileURLWithPath:imagePath];
  CGImageSourceRef source = CGImageSourceCreateWithURL((__bridge CFURLRef)url, NULL);
  if (!source) {
    reject(@"ERROR", @"无法读取图片", nil);
    return;
  }

  NSDictionary *properties = (__bridge_transfer NSDictionary *)CGImageSourceCopyPropertiesAtIndex(source, 0, NULL);
  NSNumber *orientation = properties[(NSString *)kCGImagePropertyOrientation];
  CFRelease(source);

  resolve(orientation ?: @1);
}

@end

Android端原生代码

// ImageOrientationModule.java
package com.yourprojectname; // 替换为你的项目包名

import android.media.ExifInterface;
import com.facebook.react.bridge.Promise;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.bridge.ReactContextBaseJavaModule;
import com.facebook.react.bridge.ReactMethod;

import java.io.IOException;

public class ImageOrientationModule extends ReactContextBaseJavaModule {
  public ImageOrientationModule(ReactApplicationContext reactContext) {
    super(reactContext);
  }

  @Override
  public String getName() {
    return "ImageOrientationManager";
  }

  @ReactMethod
  public void getOrientation(String imagePath, Promise promise) {
    try {
      ExifInterface exif = new ExifInterface(imagePath);
      int orientation = exif.getAttributeInt(ExifInterface.TAG_ORIENTATION, ExifInterface.ORIENTATION_NORMAL);
      promise.resolve(orientation);
    } catch (IOException e) {
      promise.reject("ERROR", "无法读取图片EXIF", e);
    }
  }
}

React Native中调用自定义模块

import { NativeModules } from 'react-native';
const { ImageOrientationManager } = NativeModules;

async function getImageOrientation(imagePath) {
  try {
    const orientation = await ImageOrientationManager.getOrientation(imagePath);
    return orientation;
  } catch (error) {
    console.error('读取方向失败:', error);
    return 1;
  }
}

// 复用方案一的宽高修正逻辑即可获取实际尺寸

内容的提问来源于stack exchange,提问作者David Burson

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 01:30:08