Java获取照片的Exif信息,并解析GPS

  • 1. 效果图
  • 2. 什么是Exif?
  • 3. 源代码
  • 参考

❤️ 这篇博客将介绍什么EXIF,以及如何用Java语言读取Exif信息,并转换经纬度为位置信息;❤️

1. 效果图

Exif包含的信息很多,示例如下:

[JPEG] - Compression Type = Baseline
[JPEG] - Data Precision = 8 bits
[JPEG] - Image Height = 3840 pixels
[JPEG] - Image Width = 1744 pixels
[JPEG] - Number of Components = 3
[JPEG] - Component 1 = Y component: Quantization table 0, Sampling factors 2 horiz/2 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
[JFIF] - Version = 1.1
[JFIF] - Resolution Units = inch
[JFIF] - X Resolution = 96 dots
[JFIF] - Y Resolution = 96 dots
[JFIF] - Thumbnail Width Pixels = 0
[JFIF] - Thumbnail Height Pixels = 0
[Exif IFD0] - Image Width = 1744 pixels
[Exif IFD0] - Image Height = 3840 pixels
[Exif IFD0] - Bits Per Sample = 8 8 8 bits/component/pixel
[Exif IFD0] - Make = HUAWEI
[Exif IFD0] - Model = ELS-AN00
[Exif IFD0] - Orientation = Unknown (0)
[Exif IFD0] - X Resolution = 72 dots per inch
[Exif IFD0] - Y Resolution = 72 dots per inch
[Exif IFD0] - Resolution Unit = Inch
[Exif IFD0] - Software = ELS-AN00 11.0.0.176(C00E170R3P6)
[Exif IFD0] - Date/Time = 2021:05:21 07:18:02
[Exif IFD0] - YCbCr Positioning = Center of pixel array
[Exif IFD0] - Device Setting Description = 105 112 112 0
[Exif SubIFD] - Document Name =
[Exif SubIFD] - Exposure Time = 2049/500000 sec
[Exif SubIFD] - F-Number = f/1.8
[Exif SubIFD] - Exposure Program = Program normal
[Exif SubIFD] - ISO Speed Ratings = 50
[Exif SubIFD] - Exif Version = 2.10
[Exif SubIFD] - Date/Time Original = 2021:05:21 07:18:02
[Exif SubIFD] - Date/Time Digitized = 2021:05:21 07:18:02
[Exif SubIFD] - Components Configuration = YCbCr
[Exif SubIFD] - Compressed Bits Per Pixel = 0.95 bits/pixel
[Exif SubIFD] - Shutter Speed Value = 1/999963864 sec
[Exif SubIFD] - Aperture Value = f/1.8
[Exif SubIFD] - Brightness Value = 0.0
[Exif SubIFD] - Exposure Bias Value = 0 EV
[Exif SubIFD] - Max Aperture Value = f/1.8
[Exif SubIFD] - Metering Mode = Multi-segment
[Exif SubIFD] - White Balance = Daylight
[Exif SubIFD] - Flash = Flash did not fire
[Exif SubIFD] - Focal Length = 4.4 mm
[Exif SubIFD] - Makernote = 65 117 116 111 0
[Exif SubIFD] - Sub-Sec Time = 242921
[Exif SubIFD] - Sub-Sec Time Original = 242921
[Exif SubIFD] - Sub-Sec Time Digitized = 242921
[Exif SubIFD] - FlashPix Version = 1.00
[Exif SubIFD] - Color Space = sRGB
[Exif SubIFD] - Exif Image Width = 1744 pixels
[Exif SubIFD] - Exif Image Height = 3840 pixels
[Exif SubIFD] - Sensing Method = One-chip color area sensor
[Exif SubIFD] - File Source = Digital Still Camera (DSC)
[Exif SubIFD] - Scene Type = Directly photographed image
[Exif SubIFD] - Custom Rendered = Custom process
[Exif SubIFD] - Exposure Mode = Auto exposure
[Exif SubIFD] - White Balance Mode = Auto white balance
[Exif SubIFD] - Digital Zoom Ratio = 1
[Exif SubIFD] - Focal Length 35 = 18 mm
[Exif SubIFD] - Scene Capture Type = Standard
[Exif SubIFD] - Gain Control = None
[Exif SubIFD] - Contrast = None
[Exif SubIFD] - Saturation = None
[Exif SubIFD] - Sharpness = None
[Exif SubIFD] - Subject Distance Range = Unknown
[Interoperability] - Interoperability Index = Recommended Exif Interoperability Rules (ExifR98)
[Interoperability] - Interoperability Version = 1.00
[GPS] - GPS Version ID = 2.200
[GPS] - GPS Latitude Ref = N
[GPS] - GPS Latitude = 40° 4’ 22.74"
[GPS] - GPS Longitude Ref = E
[GPS] - GPS Longitude = 116° 20’ 37.01"
[GPS] - GPS Altitude Ref = Below sea level
[GPS] - GPS Altitude = 0 metres
[GPS] - GPS Time-Stamp = 23:18:01.000 UTC
[GPS] - GPS Processing Method = CELLID
[GPS] - GPS Date Stamp = 2021:05:20
[Exif Thumbnail] - Image Width = 256 pixels
[Exif Thumbnail] - Image Height = 528 pixels
[Exif Thumbnail] - Compression = JPEG (old-style)
[Exif Thumbnail] - Orientation = Unknown (0)
[Exif Thumbnail] - X Resolution = 72 dots per inch
[Exif Thumbnail] - Y Resolution = 72 dots per inch
[Exif Thumbnail] - Resolution Unit = Inch
[Exif Thumbnail] - Thumbnail Offset = 1622 bytes
[Exif Thumbnail] - Thumbnail Length = 26099 bytes
[Huffman] - Number of Tables = 4 Huffman tables
[File Type] - Detected File Type Name = JPEG
[File Type] - Detected File Type Long Name = Joint Photographic Experts Group
[File Type] - Detected MIME Type = image/jpeg
[File Type] - Expected File Name Extension = jpg
[File] - File Name = mg.jpg
[File] - File Size = 1771566 bytes
[File] - File Modified Date = 星期五 七月 09 14:30:00 +08:00 2021

获取了常见的属性: 压缩格式、图像宽度、图像高度、拍摄手机、型号、手机系统版本号、gps版本、经度、纬度、高度、UTC时间戳、gps日期、iso速率、曝光时间、曝光模式、光圈值、焦距、图像色彩空间、文件源、场景类型等 效果图如下:

2. 什么是Exif?

EXIF是 Exchangeable Image File的缩写,这是一种专门为数码相机照片设定的格式。这种格式可以用来记录数字照片的属性信息,例如相机的品牌及型号、相片的拍摄时间、拍摄时所设置的光圈大小、快门速度、ISO、照片的宽度、高度等信息。

最简单易用的EXIF信息处理的Java包是Drew Noakes写的metadata-extractor,该项目最新的版本是2.16.0,支持EXIF 2.2版本。

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

  • http://www.drewnoakes.com/code/exif/ 可下载该项目的最新版本包括其源码
  • github地址:https://github.com/drewnoakes/metadata-extractor/releases?after=2.6.0

3. 源代码

获取图片的压缩格式、图像宽度、图像高度、拍摄手机、型号、手机系统版本号、gps版本、经度、纬度、高度、UTC时间戳、gps日期、iso速率、曝光时间、曝光模式、光圈值、焦距、图像色彩空间、文件源、场景类型等

pom依赖:

<!--获取相机exif信息-->
<dependency><groupId>com.drewnoakes</groupId><artifactId>metadata-extractor</artifactId><version>2.16.0</version>
</dependency>
package com.getGps;import com.drew.imaging.ImageMetadataReader;
import com.drew.imaging.ImageProcessingException;
import com.drew.imaging.jpeg.JpegMetadataReader;
import com.drew.imaging.jpeg.JpegProcessingException;
import com.drew.metadata.Directory;
import com.drew.metadata.Metadata;
import com.drew.metadata.Tag;import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;/**************************************Class Name: gpsExifInfo*Description: <获取相机经纬度并且转换实际位置>*@author: seminar*************************************/
public class GpsExifInfo {public static void main(String[] args) throws ImageProcessingException, IOException {String imgDir = "E:\\imgs";File[] files = new File(imgDir).listFiles();for (File file : files) {if (!file.getName().endsWith(".jpg")) {continue;}System.out.println("----------------------------------------\n" + file.getName());// 获取照片信息Map exifMap = readPicExifInfo(file);// 打印照片信息printPicExifInfo(exifMap);}}/*** 获取图片文件的Exif信息** @param file* @return* @throws ImageProcessingException* @throws IOException*/private static Map<String, String> readPicExifInfo(File file) throws ImageProcessingException, IOException {Map<String, String> map = new HashMap<>();Metadata metadata = ImageMetadataReader.readMetadata(file);for (Directory directory : metadata.getDirectories()) {for (Tag tag : directory.getTags()) {// 输出所有属性System.out.format("[%s] - %s = %s\n", directory.getName(), tag.getTagName(), tag.getDescription());map.put(tag.getTagName(), tag.getDescription());}if (directory.hasErrors()) {for (String error : directory.getErrors()) {System.err.format("ERROR: %s", error);}}}return map;}/*** 打印照片Exif信息** @param map*/private static void printPicExifInfo(Map<String, String> map) {String[] strings = new String[]{"Compression", "Image Width", "Image Height", "Make", "Model", "Software","GPS Version ID", "GPS Latitude", "GPS Longitude", "GPS Altitude", "GPS Time-Stamp", "GPS Date Stamp","ISO Speed Ratings", "Exposure Time", "Exposure Mode", "F-Number", "Focal Length 35", "Color Space", "File Source", "Scene Type"};String[] names = new String[]{"压缩格式", "图像宽度", "图像高度", "拍摄手机", "型号", "手机系统版本号","gps版本", "经度", "纬度", "高度", "UTC时间戳", "gps日期","iso速率", "曝光时间", "曝光模式", "光圈值", "焦距", "图像色彩空间", "文件源", "场景类型"};for (int i = 0; i < strings.length; i++) {if (map.containsKey(strings[i])) {if ("GPS Latitude".equals(strings[i]) || "GPS Longitude".endsWith(strings[i])) {System.out.println(names[i] + "  " + strings[i] + " : " + map.get(strings[i]) + ", °转dec: " + latLng2Decimal(map.get(strings[i])));} else {System.out.println(names[i] + "  " + strings[i] + " : " + map.get(strings[i]));}}}// 经纬度转location地址信息if (map.containsKey("GPS Latitude") && map.containsKey("GPS Longitude")) {convertLatLng2Loaction(latLng2Decimal(map.get("GPS Latitude")), latLng2Decimal(map.get("GPS Longitude")));}}/*** api_key:注册的百度api的key* coords:经纬度坐标* http://api.map.baidu.com/reverse_geocoding/v3/?ak="+api_key+"&output=json&coordtype=wgs84ll&location="+coords* <p>* 经纬度转地址信息** @param gps_latitude* @param gps_longitude*/private static void convertLatLng2Loaction(double gps_latitude, double gps_longitude) throws IOException {String apiKey = "FxzbLsuDDL4CS2U0M4KezOZZbGUY9iWtRn";String res = "";String url = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=" + apiKey + "&output=json&coordtype=wgs84ll&location=" + (gps_latitude + "," + gps_longitude);System.out.println("【url】" + url);CloseableHttpClient client = HttpClients.custom().build();HttpGet httpPost = new HttpGet(url);httpPost.setHeader("Content-Type", MediaType.APPLICATION_JSON_VALUE);CloseableHttpResponse resp = client.execute(httpPost);if (resp != null) {if (resp.getStatusLine().getStatusCode() == HttpStatus.SC_OK) {HttpEntity entity = resp.getEntity();res = IOUtils.readStreamAsString(entity.getContent());System.out.println("resJson: " + res);JSONObject object = JSONObject.parseObject(res);if (object.containsKey("result")) {JSONObject result = object.getJSONObject("result");if (result.containsKey("addressComponent")) {JSONObject address = object.getJSONObject("result").getJSONObject("addressComponent");System.out.println("拍摄地点:" + address.get("country") + " " + address.get("province") + " " + address.get("city") + " " + address.get("district") + " "+ address.get("street") + " " + result.get("formatted_address") + " " + result.get("business"));}}}}}/**** 经纬度坐标格式转换(* °转十进制格式)* @param gps*/public static double latLng2Decimal(String gps) {String a = gps.split("°")[0].replace(" ", "");String b = gps.split("°")[1].split("'")[0].replace(" ", "");String c = gps.split("°")[1].split("'")[1].replace(" ", "").replace("\"", "");double gps_dou = Double.parseDouble(a) + Double.parseDouble(b) / 60 + Double.parseDouble(c) / 60 / 60;return gps_dou;}
}

参考

  • 官方示例~获取方式 https://drewnoakes.com/code/exif/
  • https://blog.csdn.net/liuxiao723846/article/details/45969337
  • https://blog.csdn.net/weixin_42350212/article/details/118467097

Java获取照片的Exif信息,并解析GPS相关推荐

  1. 获取照片的EXIF信息

    版权声明 本文原创作者:谷哥的小弟 作者博客地址:http://blog.csdn.net/lfdfhl 背景概述 请利用Java编程技术获取手机拍摄的照片的EXIF信息,例如:拍摄时间.拍摄地点.经 ...

  2. 获取图片的EXIF信息如此困难?

    对于数码相机所拍摄出的图片,Exif信息非常重要.Exif是英语Exchangeable Image File(可交换图像文件)的缩写,最初由日本电子工业发展协会(JEIDA --Japan Elec ...

  3. php exif信息,php通过exif_read_data函数获取图片的exif信息

    php获取图片的exif信息,php自带一个exif_read_data函数可以用来读取图片的exif信息,代码来自php手册 echo "test1.jpg: \n"; $exi ...

  4. JS获取图片的EXIF信息+纠正图片方向

    前端图片处理碰到的一个离奇 bug , 关于图片的 EXIF 信息,特地记录下来 . 然后使用一下代码可以获取Orientation信息,并纠正Orientation带来的图片旋转问题 // from ...

  5. 通过一张照片,获取照片的地址信息

    我们如何通过一张日常照片,从中获取关键信息,确实该图片的详细位置. 例:## 通过一张照片,获取照片的地址信息这是一张消费者在一家餐厅的图片. 首先,我们先对照片进行一个整体上的观测,很明显地看出有麦 ...

  6. Java获取12306余票信息(一)

    写在前面 写给自己,也分享给大家. Java获取12306余票信息(一) Java获取12306余票信息(二) Java获取12306余票信息(三) 步骤: 首先找找12306的API 1.打开谷歌浏 ...

  7. Java获取12306余票信息(二)

    接上 前面我们说到如何用Firefox浏览器抓取数据,并 对json进行了分析,下面就是用Java代码来进行操作.以下代码都没有导入包,有需要自行导入 Java获取12306余票信息(一) Java获 ...

  8. php exif信息,php通过exif_read_data函数获取图片的exif信息_php技巧

    php获取图片的exif信息,php自带一个exif_read_data函数可以用来读取图片的exif信息,代码来自php手册 \n"; $exif = exif_read_data('te ...

  9. php exif信息,php通过exif_read_data函数获取图片的exif信息 PHP

    php获取图片的exif信息,php自带一个exif_read_data函数可以用来读取图片的exif信息,代码来自php手册 echo 'test1.jpg: \n'; $exif = exif_r ...

最新文章

  1. 皮一皮:这个职业是我想得那样吗?
  2. RocketMQ-初体验RocketMQ(01)_RocketMQ初体验
  3. 牛顿法的matlab实现,利用matlab基础语句实现牛顿法matlab潮流计算
  4. jQuery事件3——trigger触发事件
  5. PDH光端机的原理_PDH光端机的作用优点
  6. 阿里云服务器邮件发送
  7. ruby hash方法_Ruby中带有示例的Hash.rassoc(obj)方法
  8. 【codevs2492】【Tyvj1941】上帝造题的七分钟2,线段树的特别技巧
  9. 病毒或木马修改注册表,导执可执行文件无法执行的处理办法
  10. Excel 哪个版本的好用?
  11. 使用Visio 2003画UML类图之使用实现接口图标
  12. CSDN-markdown编辑器使用
  13. 【字体分享】来一波免费的漂亮英文手写体(上)
  14. HUAWEI AC+AP设备配置
  15. android爬取英文单词发音,并在app中播放。(使用百度接口)
  16. 2.8.1利用“直流扫描分析”测试基本共射放大电路电压传输特性
  17. CoreData数据库探索
  18. 智能硬件蓝牙配网方案概要
  19. 阿里云PAI平台模型压缩技术落地淘宝直播双十一应用:一猜到底
  20. 30天自制操作系统【笔记】

热门文章

  1. 微信小程序bindtap 与 catchtap 是使用
  2. Error:The SDK Build Tools revision (23.0.3) is too low for project ':app'. Minimum required is 25.0.
  3. 第三周-第08章节-Python3.5-文件修改详解
  4. HDU-1459.非常可乐(BFS )
  5. Log4Net的控制台,WinForm,WebApplication使用
  6. 作为一名合格的JAVA程序员需要点亮那些技能树?
  7. Activiti——流程执行历史记录(七)
  8. loadrunner支持https协议的操作方法-经验总结
  9. 软件工程--总作业(已经完成)
  10. 采购审批专题总结--bob