Android中读取图片EXIF元数据之metadata-extractor的使用

Posted m0_66155658

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android中读取图片EXIF元数据之metadata-extractor的使用相关的知识,希望对你有一定的参考价值。

该库能了解多种格式的元数据,其中许多可以存在于单个图像:

Exif、IPTC、XMP、JFIF / JFXX、ICC Profiles、Photoshop fields、PNG properties、BMP properties、GIF properties

它能处理类型的文件:JPEG、TIFF、PSD、PNG、BMP、GIF、Camera Raw (NEF/CR2/ORF/ARW/RW2/…)

注:并不是每个JPG图像文件都包含有EXIF信息,你可以在Windows资源管理器单击选中图片后,如果该图片包含EXIF信息,则在窗口状态栏会显示出相机的型号。

二、示例代码及描述

=========

下面我们给出一些代码将含有EXIF的图片信息全部打印出来。

示例1):

import java.io.File;

import java.util.Iterator;

import com.drew.imaging.jpeg.JpegMetadataReader;

import com.drew.metadata.Directory;

import com.drew.metadata.Metadata;

import com.drew.metadata.Tag;

import com.drew.metadata.exif.ExifDirectory;

/**

  • 读取图片的EXIF信息

*/

public class ExifTest

public static void main(String[] args) throws Exception

//包含EXIF信息的图片地址

File jpegFile = new File(“D:\\XXXX\\XXXX\\XXXX.JPG”);

Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);

Directory exif = metadata.getDirectory(ExifDirectory.class);

Iterator tags = exif.getTagIterator();

while (tags.hasNext())

Tag tag = (Tag)tags.next();

System.out.println(tag);

示例2:)

public static void main(String[] args) throws Exception

File mFile = new File(“F:/XXX.JPG”);

Metadata metadata = ImageMetadataReader.readMetadata(mFile);

for (Directory directory : metadata.getDirectories())

if(“ExifSubIFDDirectory”.equalsIgnoreCase( directory.getClass().getSimpleName() ))

//光圈F值=镜头的焦距/镜头光圈的直径

System.out.println(“光圈值: f/” + directory.getString(ExifSubIFDDirectory.TAG_FNUMBER) );

System.out.println("曝光时间: " + directory.getString(ExifSubIFDDirectory.TAG_EXPOSURE_TIME)+ “秒” );

System.out.println("ISO速度: " + directory.getString(ExifSubIFDDirectory.TAG_ISO_EQUIVALENT) );

System.out.println("焦距: " + directory.getString(ExifSubIFDDirectory.TAG_FOCAL_LENGTH) + “毫米” );

System.out.println("拍照时间: " + directory.getString(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL) );

System.out.println("宽: " + directory.getString(ExifSubIFDDirectory.TAG_EXIF_IMAGE_WIDTH) );

System.out.println("高: " + directory.getString(ExifSubIFDDirectory.TAG_EXIF_IMAGE_HEIGHT) );

if(“ExifIFD0Directory”.equalsIgnoreCase( directory.getClass().getSimpleName() ))

System.out.println("照相机制造商: " + directory.getString(ExifIFD0Directory.TAG_MAKE) );

System.out.println("照相机型号: " + directory.getString(ExifIFD0Directory.TAG_MODEL) );

System.out.println("水平分辨率: " + directory.getString(ExifIFD0Directory.TAG_X_RESOLUTION) );

System.out.println("垂直分辨率: " + directory.getString(ExifIFD0Directory.TAG_Y_RESOLUTION) );

示例3):

File mFilePath=“C://XXX.jpg”;

Metadata metadata = com.drew.imaging.jpeg.JpegMetadataReader.readMetadata(mFilePath);

JpegDirectory jd = (JpegDirectory)metadata.getDirectory(JpegDirectory.class);

System.out.println("------------" + jd.getImageHeight()); //图片的高

System.out.println("------------" + jd.getImageWidth()); //图片的宽

//由于只是读取图片的头信息,所以无论多大的图片都能读取,而且速度很快.

从执行的中可以看到照片的详细拍摄时间,拍摄用的相机型号,曝光时间,光圈值,焦距,ISO值 等等。

你也可以直接指定读取其中任意参数的值,ExifDirectory 类中定义了很多以 TAG_ 开头的整数常量,这些常量代表特定的一个参数值,例如要读取相机的型号,可以用下面代码来获取。

Metadata metadata = JpegMetadataReader.readMetadata(jpegFile);

Directory exif = metadata.getDirectory(ExifDirectory.class);

String model = exif.getString(ExifDirectory.TAG_MODEL);

上述提到的是如何获取照片的EXIF信息,其中包含一个很重要的信息就是——拍摄方向。例如所用的图片拍摄方向是:Orientation - Top, left side (Horizontal / normal)。我们在拍照的时候经常会根据场景的不同来选择相机的方向,例如拍摄一颗高树,我们会把相机竖着拍摄,使景物刚好适合整个取景框,但是这样得到的图片如果用普通的图片浏览器看便是倒着的,需要调整角度才能得到一个正常的图像。

通过读取图片的EXIF信息,可以得到关于拍摄方向的这样一个结果:Orientation - Left side, bottom (Rotate 270 CW)

而直接读取 ExitDirectory.TAG_ORIENTATION 标签的值是8。

来看下这个项目是如何来定义这些返回值的,打开源码包中的ExifDescriptor类的getOrientationDescription(),该方法代码如下:

public String getOrientationDescription() throws MetadataException

if (!_directory.containsTag(ExifDirectory.TAG_ORIENTATION)) return null;

int orientation = _directory.getInt(ExifDirectory.TAG_ORIENTATION);

switch (orientation)

case 1: return “Top, left side (Horizontal / normal)”;

case 2: return “Top, right side (Mirror horizontal)”;

case 3: return “Bottom, right side (Rotate 180)”;

case 4: return “Bottom, left side (Mirror vertical)”;

case 5: return “Left side, top (Mirror horizontal and rotate 270 CW)”;

case 6: return “Right side, top (Rotate 90 CW)”;

case 7: return “Right side, bottom (Mirror horizontal and rotate 90 CW)”;

case 8: return “Left side, bottom (Rotate 270 CW)”;

default:

return String.valueOf(orientation);

从这个方法可以清楚看到各个返回值的意思,如此我们便可以根据实际的返回值来对图像进行旋转或者是镜像处理了。

下面给出代码用以旋转图片,其他的关于图片的镜像等处理读者可以依此类推:

String mPath = “D:\\XXX.JPG”;

File img = new File(mPath);

BufferedImage old_img = (BufferedImage)ImageIO.read(img);

int w = old_img.getWidth();

int h = old_img.getHeight();

BufferedImage new_img = new BufferedImage(h,w,BufferedImage.TYPE_INT_BGR);

Graphics2D g2d =new_img.createGraphics();

AffineTransform origXform = g2d.getTransform();

AffineTransform newXform = (AffineTransform)(origXform.clone());

// center of rotation is center of the panel

double xRot = w/2.0;

newXform.rotate(Math.toRadians(270.0), xRot, xRot); //旋转270度

g2d.setTransform(newXform);

// draw image centered in panel

g2d.drawImage(old_img, 0, 0, null);
aphics();

AffineTransform origXform = g2d.getTransform();

AffineTransform newXform = (AffineTransform)(origXform.clone());

// center of rotation is center of the panel

double xRot = w/2.0;

newXform.rotate(Math.toRadians(270.0), xRot, xRot); //旋转270度

g2d.setTransform(newXform);

// draw image centered in panel

g2d.drawImage(old_img, 0, 0, null);

在 Qt 中读取图像的 exif 元数据

【中文标题】在 Qt 中读取图像的 exif 元数据【英文标题】:Read exif metadata of images in Qt 【发布时间】:2013-02-28 06:08:41 【问题描述】:

在我的 Qt 应用程序中,我想读取图像的 exif 数据。 QImageQPixmap 似乎没有提供这样的钩子。

Qt 中是否有任何 API 允许在不使用 libexif 等外部库的情况下读取 exif?

编辑:这是this的副本

【问题讨论】:

重复***.com/questions/4105534/… 【参考方案1】:

从 qt 扩展框架中尝试QExifImageHeader。 qtextended.org 对我不可用?但您可以搜索其他下载镜像。

【讨论】:

【参考方案2】:

QImageReader 有一个名为 transformation() 的方法,它是在 5.5 版本中引入的,首先你应该尝试一下。

您还可以查看以下链接,了解如何在 Qt 中使用 Windows GDI,http://amin-ahmadi.com/2015/12/17/how-to-read-image-orientation-in-qt-using-stored-exif/

【讨论】:

【参考方案3】:

对我来说,最好的选择是easyexif by Mayank Lahiri。您只需要将exif.cpp和exif.h这两个文件添加到您的项目中即可。

int main(int argc, char *argv[])

    for (int i=1; i<argc; ++i)
        QFile file(argv[i]);
        if (file.open(QIODevice::ReadOnly))
            QByteArray data = file.readAll();
            easyexif::EXIFInfo info;
            if (int code = info.parseFrom((unsigned char *)data.data(), data.size()))
                qDebug() << "Error parsing EXIF: code " << code;
                continue;
            
            qDebug() << "Camera model         : " << info.Model.c_str();
            qDebug() << "Original date/time   : " << info.DateTimeOriginal.c_str();
         else
            qDebug() << "Can't open file:" << argv[i];           
    

    return 0;

【讨论】:

以上是关于Android中读取图片EXIF元数据之metadata-extractor的使用的主要内容,如果未能解决你的问题,请参考以下文章

EXIF.Js:读取图片的EXIF信息

在 Qt 中读取图像的 exif 元数据

Exif.js读取图像的元数据

Exif.js 读取图像的元数据

Exif.js 读取图像的元数据

为啥 PHAsset creationDate 与 exif 元数据不同?