解决ffmpeg缩放图片后方向错乱问题

337 阅读2分钟

最近收到反馈说云盘(内部项目)中的有一些缩略图方向错了, 用手机拍的竖图, 传到云盘后, 在手机上看图是躺着的. 第一时间想到是不是因为heif 图转jpeg 过程中元数据丢失造成. (之前处理过此问题, 因为libheif 库低于 1.4.0的版本上存在此问题). 后来找到测试图片发现是 jpeg 的. 因为jpeg 图片在上传到云盘后也会利用ffmpeg 生成各种尺寸的缩略图, 所以应该 ffmpeg 的问题, 于是在 stackoverflow 上找了一下, "ffmpeg image rotate" , 看到个相同问题(stackoverflow.com/questions/3…). 原来是 ffmpeg 在处理过程中, 把图片的 orientation元数据给丢掉了. 导致转出来的图在显示时方向是错的. 查了一下ffmpeg 文档, 没有找到相关参数选项来保留orientation 属性, 也未找到如何通过 ffmpeg 来提取及设置该属性.

所以只好来试试专注于提取,写入及修改媒体元数据的工具exiftool (exiftool.org/), 比较方便的是exiftool 提供可以执行程序下载, 而不需要自己编译及依赖各种第三方库. 下载后只需要一个命令行程序加 lib目录即可运行.

读取orientation

# exiftool -Orientation -n -S ~/Downloads/11111.jpg 
# Orientation: 6

# exiftool -Orientation ~/Downloads/11111.jpg
# Orientation                     : Rotate 90 CW

注意有两种格式输出, 一种是加 -n 参数, 输出数值型方向值, 不加 -n参数, 输出的是字符串类型的方向描述, 其中两者的对应关系为:

1 = Horizontal (normal)
2 = Mirror horizontal
3 = Rotate 180
4 = Mirror vertical
5 = Mirror horizontal and rotate 270 CW
6 = Rotate 90 CW
7 = Mirror horizontal and rotate 90 CW
8 = Rotate 270 CW

写入 orientation

# exiftool -n -Orientation=6 ~/Downloads/1111_320.jpeg
# 1 image files updated

解决问题

获取orientation: exiftool -Orientation -n -S 11111.jpg
图片缩放:  ffmpeg -i 11111.jpg -vf scale=320:320:force_original_aspect_ratio=increase -f image2 -frames:v 1 11111_320.jpg 
写入orientation: exiftool -n -Orientation=x 11111_320.jpg