您的浏览器过于古老 & 陈旧。为了更好的访问体验, 请 升级你的浏览器
二周 发布于2019年11月26日 22:46 最近更新于 2019年11月27日 15:04

原创 Java 读取图片EXIF信息

2395 次浏览 读完需要≈ 18 分钟 Java

内容目录

EXIF代表“可交换图像文件格式”。这种类型的信息是根据TIFF规范格式化的,可以在JPG,TIFF,PNG,JP2,PGF,MIFF,HDP,PSP和XCF图像以及许多基于TIFF的RAW图像,甚至某些AVI中找到和MOV视频。

比如随便打开一张图片,可以看到这张图片的很多信息:

EXIF.png
EXIF.png
读取EXIF信息

metadata-extractor 是一个开源的,经过广泛验证并且被很多大企业(如Apache,IBM等)使用的一个库,有 Java 和 .Net 两种语言。这里我们演示 Java 语言。代码都很简单,这里是 GitHub地址,添加依赖什么的我就不再说了。

package com.smile.test;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import org.juniTestExift.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.util.Date;

public class TestExif {
	@Test
	public void viewExif() throws ImageProcessingException, IOException {
		final String jpegPath = "/Users/smile/Desktop/demo.jpg";
		File jpegFile = new File(jpegPath);
		Metadata metadata = ImageMetadataReader.readMetadata(jpegFile);
		// 打印所有Tag
		for (Directory directory : metadata.getDirectories()) {
			for (Tag tag : directory.getTags()) {
				System.out.println(tag);
			}
		}
		// obtain the Exif directory
		ExifSubIFDDirectory directory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);

		// 查询特定Tag:拍摄日期(OS X上叫内容创建时间)
		Date date = directory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL);
	}
}

他的输出可能是这样的(不完整):

[JPEG] Compression Type - Baseline
[JPEG] Data Precision - 8 bits
[JPEG] Image Height - 3619 pixels
[JPEG] Image Width - 2714 pixels
[JPEG] Number of Components - 3
[JPEG] Component 1 - Y component: Quantization table 0, Sampling factors 1 horiz/1 vert
[JPEG] Component 2 - Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert
[JPEG] Component 3 - Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert
[Exif IFD0] Image Width - 3024 pixels
[Exif IFD0] Image Height - 4032 pixels
[Exif IFD0] Bits Per Sample - 8 8 8 bits/component/pixel
[Exif IFD0] Photometric Interpretation - RGB
[Exif IFD0] Make - Apple
[Exif IFD0] Model - iPhone XS Max
[Exif IFD0] Orientation - Top, left side (Horizontal / normal)
[Exif IFD0] Samples Per Pixel - 3 samples/pixel
[Exif IFD0] X Resolution - 72 dots per inch
[Exif IFD0] Y Resolution - 72 dots per inch
[Exif IFD0] Resolution Unit - Inch
[Exif IFD0] Software - Adobe Photoshop CS6 (Windows)
[Exif IFD0] Date/Time - 2019:11:26 10:42:47

上面这些信息可能都没啥用,下面我们就演示输出上面第一张图中的信息:

EXIF信息查询

EXIF的信息是用tag来标记的:GitHub上列出了常用的标签完整的标签列表在这里

package com.smile.test;

import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.MetadataException;
import com.drew.metadata.Tag;
import com.drew.metadata.exif.ExifIFD0Directory;
import com.drew.metadata.exif.ExifSubIFDDirectory;
import com.drew.metadata.exif.ExifThumbnailDirectory;
import com.drew.metadata.file.FileSystemDirectory;
import com.drew.metadata.jpeg.*;
import org.junit.jupiter.api.Test;

import java.io.File;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.TimeZone;

public class TestExif {
	
	@Test
	public void queryExif() throws ImageProcessingException, IOException, MetadataException {
		final String jpegPath = "/Users/smile/Desktop/demo.jpg";
		File jpegFile = new File(jpegPath);
		Metadata metadata = ImageMetadataReader.readMetadata(jpegFile);
		// obtain the Exif directory
		ExifSubIFDDirectory exifSubIFDDirectory = metadata.getFirstDirectoryOfType(ExifSubIFDDirectory.class);
		ExifIFD0Directory exifIFD0Directory = metadata.getFirstDirectoryOfType(ExifIFD0Directory.class);
		FileSystemDirectory fileSystemDirectory = metadata.getFirstDirectoryOfType(FileSystemDirectory.class);
		ExifThumbnailDirectory exifThumbnailDirectory = metadata.getFirstDirectoryOfType(ExifThumbnailDirectory.class);
		JpegDirectory jpegDirectory = metadata.getFirstDirectoryOfType(JpegDirectory.class);


		print("创建时间", exifIFD0Directory.getDate(ExifIFD0Directory.TAG_DATETIME, TimeZone.getDefault()));
		print("修改时间", fileSystemDirectory.getDate(FileSystemDirectory.TAG_FILE_MODIFIED_DATE, TimeZone.getDefault()));
		print("内容创建时间", exifSubIFDDirectory.getDate(ExifSubIFDDirectory.TAG_DATETIME_ORIGINAL, TimeZone.getDefault()));
		print("尺寸", jpegDirectory.getInt(JpegDirectory.TAG_IMAGE_WIDTH) + "x" + jpegDirectory.getInt(JpegDirectory.TAG_IMAGE_HEIGHT));
		print("分辨率", exifThumbnailDirectory.getInt(ExifThumbnailDirectory.TAG_X_RESOLUTION) + "x" + exifThumbnailDirectory.getString(ExifThumbnailDirectory.TAG_Y_RESOLUTION));
		print("色彩空间", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_COLOR_SPACE));
		print("设备制造商", exifIFD0Directory.getString(ExifIFD0Directory.TAG_MAKE));
		print("设备型号", exifIFD0Directory.getString(ExifIFD0Directory.TAG_MODEL));
		print("镜头型号", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_LENS_MODEL));
		print("光圈值", exifSubIFDDirectory.getDouble(ExifSubIFDDirectory.TAG_APERTURE));
		print("曝光时间", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_EXPOSURE_TIME));
		print("焦距", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_FOCAL_LENGTH) + "毫米");
		print("ISO感光度", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_ISO_EQUIVALENT));
		print("闪光灯", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_FLASH));
		print("光圈数", "f/" + exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_FNUMBER));
		print("测光模式", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_METERING_MODE));
		print("白平衡", exifSubIFDDirectory.getString(ExifSubIFDDirectory.TAG_WHITE_BALANCE_MODE));
		print("内容创作者", exifIFD0Directory.getString(ExifIFD0Directory.TAG_SOFTWARE));
	}


	public void print(String tag, Object value) {
		final SimpleDateFormat formatter = new SimpleDateFormat("yyyy年MM月dd日 a h:mm");
		String v = "";
		if (value != null) {
			if (value instanceof Date) {
				v = formatter.format(value);
			} else {
				v = value.toString();
			}
		}
		System.out.println(String.format("%15s\t\t\t%s", tag, v));
	}
}

你的输出可能是这样的:

           创建时间			2019年11月26日 上午 10:42
           修改时间			2019年11月26日 上午 10:42
         内容创建时间			2019年04月16日 下午 8:00
             尺寸			2714x3619
            分辨率			72x72
           色彩空间			65535
          设备制造商			Apple
           设备型号			iPhone XS Max
           镜头型号			iPhone XS Max back dual camera 4.25mm f/1.8
            光圈值			1.6959938128383605
           曝光时间			0.04
             焦距			4.25毫米
         ISO感光度			500
            闪光灯			16
            光圈数			f/1.8
           测光模式			5
            白平衡			0
          内容创作者			Adobe Photoshop CS6 (Windows)
  • CodePlayer技术交流群1
  • CodePlayer技术交流群2

0 条评论

撰写评论