相关文章推荐
高兴的猴子  ·  Nat. Mach. Intell. | ...·  10 月前    · 
奋斗的奔马  ·  PHP cURL: ...·  10 月前    · 
满身肌肉的熊猫  ·  How to solve error :" ...·  1 年前    · 

本文已参与「新人创作礼」活动, 一起开启掘金创作之路。

前段时间写了篇 杀鸡用牛刀,FFmpeg API 加载存储图片,比 ImageMagic 和 stb_image 快多了 ,后来发现有个问题,有些 JPG 图片是带有旋转信息的,如果只解码,不获取它的旋转信息,将导致图片的方向错误。

Exif 是什么

Exif就是用来记录拍摄图像时的各种信息:图像信息(厂商,分辨率等),相机拍摄记录(ISO,白平衡,饱和度,锐度等),缩略图(缩略图宽度,高度等),gps(拍摄时的经度,纬度,高度)等,将这些信息按照JPEG文件标准放在图像文件头部。Exchangeable Image File(可交换图像文件)的缩写,实际是JPEG文件的一种,遵从JPEG标准,只是在文件头信息中增加了有关拍摄信息的内容和索引图。

简单来说,EXIF 信息就是由数码相机在拍摄过程中采集一系列的信息,然后把信息放置在我们熟知的 JPEG/TIFF 文件的头部, 也就是说 EXIF 信息是镶嵌在 JPEG/TIFF 图像文件格式内的一组拍摄参数,主要包括摄影时的光圈、快门、ISO、日期时间等各种与当时摄影条件相关的讯息,相机品牌型号,色彩编码,拍摄时录制的声音以及全球定位系统(GPS)等信息。 简单的说,它就好像是傻瓜相机的日期打印功能一样,只不过 EXIF 信息所记录的资讯更为详尽和完备。

av_dict_get

那如何才能用 FFmpeg 来获取 JPG 的旋转信息呢?查过很多资料,最后终于找到一种方法。由于再次查找时又要翻阅多篇文章,因此记录在此。答案就是使用 av_dict_get 这个方法。

首先,要完成使用 FFmpeg 对 JPG 图片的解码过程,得到解码后的帧图像 AVFrame ,然后,在 AVFrame->metadata 中读取 Orientation 来获取旋转信息。其中 Orientation 的定义如下:

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

整个功能的具体代码如下:

  AVDictionaryEntry *e = av_dict_get(frame_->metadata, "Orientation", nullptr, 0);
  if (e) {
    string s = e->value;
    if (s.find("6") != string::npos || s.find("7") != string::npos) {
      return 90;
    } else if (s.find("1") != string::npos || s.find("2") != string::npos) {
      return 0;
    } else if (s.find("8") != string::npos || s.find("5") != string::npos) {
      return 270;
    } else if (s.find("3") != string::npos || s.find("4") != string::npos) {
      return 180;

同理,可以通过将参数 Orientation 改为 EXIF 信息中的其他信息名称,来获取图片的其他 EXIF 信息。

  • 私信