iOS手机竖着拍的照片被旋转了90°的原因以及解决方案

exif.js 获取图像的拍照方向的代码如下:

EXIF.getData(IMG_FILE, function () { // IMG_FILE为图像数据

var orientation = EXIF.getTag(this, “Orientation”);

console.log(“Orientation:” + orientation); // 拍照方向

});

获取拍照方向的结果为1-8的数字:

在这里插入图片描述

注意:对于上面的八种方向中,加了*的并不常见,因为它们代表的是镜像方向,如果不做任何的处理,不管相机以任何角度拍摄,都无法出现镜像的情况。

这个表格代表什么意义?我们来看第一行,值为1时,右边两列的值分别为:Row #0 is Top,Column #0 is Left side,其实很好理解,它表示照片的第一行位于顶端,而第一列位于左侧,那么这张照片自然就是以正常角度拍摄的。

而这8种结果,就是第一行与第一列所在的位置的8种组合。

测试发现

(1)iOS手机横着拍的照片,照片方向显示正常。

(2) iOS手机竖着拍的照片,照片旋转了90度

测试发现照片Orientaion信息为:1、3、6、8四种状态。

我们在前端对图片进行像素处理或者drawInRect等操作之后,照片的Orientaion信息,即为拍照方向信息被删除了,所以iOS手机竖着拍的照片又回到了横着的状态,看起来也就是逆时针旋转了90°!

那么如何纠正这个旋转角度呢?

其实思路也很简单:在处理图片之前

<think>我们正在讨论视频处理中的方向问题。用户询问获取视频方向的原因以及是否可以省略该步骤。结合引用内容,特别是引用[1]中提到的问题:如果不处理旋转,获取的YUV数据可能是倒立的,这会影响后续处理(如水印添加)。因此,我们需要解释为什么需要获取视频方向。 原因: 1. 视频元数据中的旋转信息:许多现代视频文件(尤其是移动设备录制的)包含旋转元数据(如90°、180°、270°旋转)。这是因为设备在录制视频时,传感器方向可能不同,但视频数据本身通常以横向存储,通过旋转标记指示正确播放方向。 2. 显示与处理需求:如果不处理旋转,直接解码得到的帧可能是旋转后的(如倒立或侧躺),导致显示不正确或后续处理(如目标检测、水印)在错误的方向上进行。 是否可以省略? - 如果确定视频源不会出现旋转(如专业摄像机摄的横向视频),则可以省略。 - 但通常,特别是处理用户上传的视频(来自手机)时,必须处理旋转,否则会出现方向错误。 引用[1]中FFmpeg的例子说明,忽略旋转会导致处理后的视频方向错误。同样,在iOS中,我们通过`preferredTransform`获取旋转矩阵,然后对每一帧应用变换来纠正方向。 因此,步骤3(获取视频方向信息)是必要的,除非你能确保所有输入视频都是横向且无旋转。 在代码中,我们通过以下方式处理: ```swift let preferredTransform = try await videoTrack.load(.preferredTransform) // ... 然后对每一帧应用这个变换 ``` 如果不处理旋转,那么当视频有旋转标记时,你得到的像素缓冲区将是未校正的,可能导致显示异常。 总结:获取视频方向是为了正确显示和处理视频帧,对于大多数消费级视频(尤其是手机摄的)是必要步骤。 相关问题: 1. 如何检测视频是否包含旋转信息? 2. 除了iOS,Android平台如何处理视频旋转? 3. 视频旋转信息在哪些元数据中存储? 4. 如何在不旋转像素数据的情况下正确显示旋转视频(通过渲染时调整)? 5. 旋转处理对视频处理性能的影响如何?</think>### 获取视频方向的原因及必要性分析 #### 为什么需要获取视频方向? 视频方向信息(通常存储在`preferredTransform`属性中)是视频处理的关键元数据,主要原因包括: 1. **设备物理方向差异** 移动设备摄视频时,传感器会根据设备方向(竖屏/横屏)自动旋转图像数据,但原始像素数据始终以传感器物理方向存储。例如: - 竖屏摄时,实际像素数据是横向的(90°旋转) - 倒置摄时,像素数据是180°旋转的 $$ \text{旋转矩阵} = \begin{bmatrix} \cos\theta & -\sin\theta \\ \sin\theta & \cos\theta \end{bmatrix} $$ 2. **显示一致性需求** 若不处理方向,解码后的帧会出现方向错误(如倒立、侧躺),如引用[1]所述:*"获取YUV的时候其实倒立着的"*[^1] 3. **处理准确性保证** 后续处理(如添加水印、目标检测)需要在正确方向上进行: - 水印位置会错乱 - 人脸检测可能失效 - 运动追踪产生偏差 4. **跨平台兼容性** 如引用[2]所示,Android同样需要处理方向元数据[^2],iOS的`preferredTransform`与Android的`MediaMetadataRetriever.METADATA_KEY_VIDEO_ROTATION`作用相同 #### 是否可以省略该步骤? | 场景 | 是否可省略 | 风险说明 | |------|------------|----------| | **仅播放视频** | ✅ 可省略 | 播放器会自动应用旋转矩阵 | | **帧级处理**<br>(水印/分析/编辑) | ❌ 不可省略 | 处理结果会方向错乱 | | **保存处理结果** | ❌ 不可省略 | 新文件将保留原始方向错误 | | **已知固定方向源** | ✅ 可省略 | 需确保所有输入视频方向一致 | #### 关键结论 1. **必须获取方向**的场景: - 任何需要访问/修改像素数据的操作(引用[3]中计算机视觉应用[^3]) - 生成新视频文件(引用[4]中URL处理[^4]) - 需要精确空间定位的处理(如AR叠加) 2. **可省略**的场景: - 仅使用`AVPlayer`播放视频 - 处理专业摄像机摄的横向视频 - 实时预览但不需要保存结果 ### 方向处理最佳实践 ```swift // 1. 获取方向矩阵 let transform = try await track.load(.preferredTransform) // 2. 判断是否需要处理 guard !transform.isIdentity else { return pixelBuffer } // 3. 应用旋转(引用[1]的解决方案[^1]) let correctedBuffer = applyTransform( original: pixelBuffer, rotation: atan2(transform.b, transform.a) // 计算旋转 ) ``` ### 相关问题 1. **如何在不旋转像素数据的情况下正确处理方向?** 可通过设置`AVPlayerLayer`的`videoGravity`或`CGAffineTransform`在渲染时修正[^2] 2. **视频方向信息存储在文件什么位置?** 通常位于MOOV原子盒的`tkhd`(Track Header)或`udta`(User Data)中 3. **处理方向对性能有多大影响?** 每帧旋转会增加15-30%的CPU消耗,建议使用Metal/GPU加速 4. **如何检测视频是否包含旋转信息?** ```swift let hasRotation = !(try await track.load(.preferredTransform).isIdentity) ``` 5. **为什么有些视频的`preferredTransform`返回零矩阵?** 通常表示文件缺失方向元数据,需根据设备型号或创建时间启发式判断 6. **方向处理错误会导致哪些常见问题?** - 人脸检测失效(如引用[3]的CV应用[^3]) - 运动矢量分析错误 - 地理标签定位偏差 - 水印位置错乱(如引用[1]描述[^1])
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值