通过Java技术手段,某程序员发现自己被绿了!

共 10475字,需浏览 21分钟

 ·

2021-10-29 01:10

点击关注公众号,回复“2T”获取2TB学习资源!
互联网架构师后台回复 2T 有特别礼包
作者:肥仔哥哥1930
来源:https://blog.csdn.net/zwrlj527/article/details/119823407

上一篇:为什么阿里巴巴禁止使用存储过程?


今早,看到CSDN里推荐的Python获取女朋友发来加班拍照定位地址是酒店的段子,本来准备验证下,顺便练练手的,最后,安装执行pip install json报没有指定版本号。一怒之下搞我大JAVA,验证可行与场景体遐想。废话不多说,先上硬货。


依赖导入


从博文上看是exifread模块,找我大java的对应的jar,发现metadata-extractor,而且官方还在持续更新,最近的jar是今年的。



这个元数据提取jar非常强大,还支持视频信息的提取,看看官方介绍:


看到没,第一个示例,就写的支持我大JAVA,让我犹如鸡血冲顶,在支持同事联调事件工单的同时,大肝这块。


<dependency>    <groupId>com.drewnoakes</groupId>    <artifactId>metadata-extractor</artifactId>    <version>2.16.0</version></dependency>


准备工作


1、室外空旷地点打开GPS


2、百度地图、北斗伴验证已连接到GPS定位



3、设置手机带的照相机开启位置信息



4、拍照一张顺便查看照片详情



这里一定要确定拍的照片的详情时有经纬度信息的,如果没有,你针对你的手机在CSDN里搜索下怎么设置。这里顺便提下,CSDN的浏览器插件真香。简直就是我们技术人事的福音,再以不用担心某某度的广告之类导致找东西费劲了,而且它很包容,还时可以选择自己喜欢的搜索引擎的。



示例demo


这里先演示这个元数据提取jar能提取到的信息,顺便把取到的经纬度通过百度转地址。


因为是demo,没有业务,我这里就直接在测试类里干了。没有什么业务,不涉及什么机密,可以上全码。


package com.easylinkin.bm.extractor;

import com.alibaba.fastjson.JSONObject;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.easylinkin.bm.util.HttpUtils;import lombok.extern.slf4j.Slf4j;

import java.io.File;import java.io.IOException;

/** * @author zhengwen **/@Slf4jpublic class ImgTestCode { public static void main(String[] args) throws Exception {

File file = new File("C:\\Users\\zhengwen\\Desktop\\test\\IMG_20210820_093958.jpg"); readImageInfo(file); }

/** * 提取照片里面的信息 * * @param file 照片文件 * @throws ImageProcessingException * @throws Exception */ private static void readImageInfo(File file) throws ImageProcessingException, Exception { Metadata metadata = ImageMetadataReader.readMetadata(file);

System.out.println("---打印全部详情---"); for (Directory directory : metadata.getDirectories()) { for (Tag tag : directory.getTags()) { System.out.format("[%s] - %s = %s\n", directory.getName(), tag.getTagName(), tag.getDescription()); } if (directory.hasErrors()) { for (String error : directory.getErrors()) { System.err.format("ERROR: %s", error); } } }

System.out.println("--打印常用信息---");
Double lat = null; Double lng = null; for (Directory directory : metadata.getDirectories()) { for (Tag tag : directory.getTags()) { String tagName = tag.getTagName(); //标签名 String desc = tag.getDescription(); //标签信息 if (tagName.equals("Image Height")) { System.err.println("图片高度: " + desc); } else if (tagName.equals("Image Width")) { System.err.println("图片宽度: " + desc); } else if (tagName.equals("Date/Time Original")) { System.err.println("拍摄时间: " + desc); } else if (tagName.equals("GPS Latitude")) { System.err.println("纬度 : " + desc); System.err.println("纬度(度分秒格式) : " + pointToLatlong(desc)); lat = latLng2Decimal(desc); } else if (tagName.equals("GPS Longitude")) { System.err.println("经度: " + desc); System.err.println("经度(度分秒格式): " + pointToLatlong(desc)); lng = latLng2Decimal(desc); } } } System.err.println("--经纬度转地址--"); //经纬度转地主使用百度api convertGpsToLoaction(lat, lng);



}

/** * 经纬度格式 转换为 度分秒格式 ,如果需要的话可以调用该方法进行转换 * * @param point 坐标点 * @return */ public static String pointToLatlong(String point) { Double du = Double.parseDouble(point.substring(0, point.indexOf("°")).trim()); Double fen = Double.parseDouble(point.substring(point.indexOf("°") + 1, point.indexOf("'")).trim()); Double miao = Double.parseDouble(point.substring(point.indexOf("'") + 1, point.indexOf("\"")).trim()); Double duStr = du + fen / 60 + miao / 60 / 60; return duStr.toString(); }

/*** * 经纬度坐标格式转换(* °转十进制格式) * @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; }

/** * 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 convertGpsToLoaction(double gps_latitude, double gps_longitude) throws IOException { String apiKey = "YNxcSCAphFvuPD4LwcgWXwC3SEZZc7Ra";

String res = ""; String url = "http://api.map.baidu.com/reverse_geocoding/v3/?ak=" + apiKey + "&output=json&coordtype=wgs84ll&location=" + (gps_latitude + "," + gps_longitude); System.err.println("【url】" + url);

res = HttpUtils.httpGet(url); 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.err.println("拍摄地点:" + address.get("country") + " " + address.get("province") + " " + address.get("city") + " " + address.get("district") + " " + address.get("street") + " " + result.get("formatted_address") + " " + result.get("business")); } } }

}


控制台打印:



下面贴出详细内容:


com.easylinkin.bm.extractor.ImgTestCode---打印全部详情---[JPEG] - Compression Type = Baseline[JPEG] - Data Precision = 8 bits[JPEG] - Image Height = 4032 pixels[JPEG] - Image Width = 3024 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[Exif IFD0] - Date/Time = 2021:08:20 09:39:58[Exif IFD0] - Model = YOTA Y3[Exif IFD0] - YCbCr Positioning = Center of pixel array[Exif IFD0] - Resolution Unit = Inch[Exif IFD0] - Y Resolution = 72 dots per inch[Exif IFD0] - X Resolution = 72 dots per inch[Exif IFD0] - Make = YOTA[GPS] - GPS Date Stamp = 2021:08:20[GPS] - GPS Altitude Ref = Below sea level[GPS] - GPS Longitude Ref = E[GPS] - GPS Longitude = 114° 24' 9.61"[GPS] - GPS Processing Method = ASCII[GPS] - GPS Latitude Ref = N[GPS] - GPS Time-Stamp = 01:39:46.000 UTC[GPS] - GPS Altitude = 21 metres[GPS] - GPS Latitude = 30° 28' 40.67"[Exif SubIFD] - Color Space = sRGB[Exif SubIFD] - F-Number = f/1.9[Exif SubIFD] - Date/Time Digitized = 2021:08:20 09:39:58[Exif SubIFD] - Focal Length = 3.9 mm[Exif SubIFD] - Aperture Value = f/1.9[Exif SubIFD] - Exposure Mode = Auto exposure[Exif SubIFD] - Sub-Sec Time Digitized = 819350[Exif SubIFD] - Exif Image Height = 4032 pixels[Exif SubIFD] - Focal Length 35 = 23 mm[Exif SubIFD] - Scene Capture Type = Standard[Exif SubIFD] - Sub-Sec Time Original = 819350[Exif SubIFD] - Exposure Program = Unknown (0)[Exif SubIFD] - White Balance Mode = Auto white balance[Exif SubIFD] - Exif Image Width = 3024 pixels[Exif SubIFD] - Sub-Sec Time = 819350[Exif SubIFD] - Shutter Speed Value = 1/1022 sec[Exif SubIFD] - Metering Mode = Center weighted average[Exif SubIFD] - Date/Time Original = 2021:08:20 09:39:58[Exif SubIFD] - Components Configuration = YCbCr[Exif SubIFD] - Exif Version = 2.20[Exif SubIFD] - Flash = Flash did not fire[Exif SubIFD] - Brightness Value = 0.0[Exif SubIFD] - ISO Speed Ratings = 103[Exif SubIFD] - Sensing Method = One-chip color area sensor[Exif SubIFD] - FlashPix Version = 1.00[Exif SubIFD] - Exposure Time = 1/1023 sec[Interoperability] - Interoperability Index = Recommended Exif Interoperability Rules (ExifR98)[Interoperability] - Interoperability Version = 1.00[Exif Thumbnail] - Y Resolution = 72 dots per inch[Exif Thumbnail] - Thumbnail Length = 21538 bytes[Exif Thumbnail] - Thumbnail Offset = 959 bytes[Exif Thumbnail] - Compression = JPEG (old-style)[Exif Thumbnail] - Resolution Unit = Inch[Exif Thumbnail] - X Resolution = 72 dots per inch[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 = IMG_20210820_093958.jpg[File] - File Size = 5215044 bytes[File] - File Modified Date = 星期五 八月 20 09:39:59 +08:00 2021--打印常用信息---初始化HttpClientTest~~~开始图片高度: 4032 pixels图片宽度: 3024 pixels经度: 114° 24' 9.61"经度(度分秒格式): 114.40266944444446纬度 : 30° 28' 40.67"纬度(度分秒格式) : 30.477963888888887拍摄时间: 2021:08:20 09:39:58--经纬度转地址--【url】http://api.map.baidu.com/reverse_geocoding/v3/?ak=YNxcSCAphFvuPD4LwcgWXwC3SEZZc7Ra&output=json&coordtype=wgs84ll&location=30.477963888888887,114.40266944444446初始化HttpClientTest~~~结束拍摄地点:中国 湖北省 武汉市 洪山区 软件园路 湖北省武汉市洪山区软件园路9 关山,光谷天地


上面的提取到的内容我就不解释了,应该看得懂,不懂的,可以翻译英文,或者查API看打印的是啥。


其他文件我就不演示了,有兴趣的可以自己试试。


我的百度地图的AK就先放这里,方便大家验证,免得说我骗人,反正我也是免费用的。


最后再说一句,图片发送要么压缩到压缩包再发送,要么用数据线从手机里拷出来。我这里先用微信发的,基本上信息都被抹除了(在电脑上查看图片详情,其实也可以看到经纬度信息的)。


还有,我还有个苹果手机,其实也是可以拍有地理位置信息的照片的,要打开隐私里的定位,授权照相机。


总结与衍生想法


这个怎么说呢,还是很不错的。用到我们的工作中的话,我们觉得可以替代我们之前做的一个打点巡检的,到达巡检位置拍张照片再配合机器码,不怕你让别人代拍照片了。还有考勤的公出单、外勤等等。


另外还想到这出门在外爱拍照的娃们,你们的照片放到云存储上,然后如果有无良服务商,基本可以把你的轨迹通过你上传的照片时间绘制出来。。。


好了,这个就分享到这里。这里其实还给我一个最大的感受就是,如果我不知道A就不会想到B。要是我早知道图片可以携带的信息,或者知道照相机软件可以获取的信息,可能可以针对这些早点做点什么。。。


感谢您的阅读,也欢迎您发表关于这篇文章的任何建议,关注我,技术不迷茫!小编到你上高速。

    · END ·
最后,关注公众号互联网架构师,在后台回复:2T,可以获取我整理的 Java 系列面试题和答案,非常齐全


正文结束


推荐阅读 ↓↓↓

1.不认命,从10年流水线工人,到谷歌上班的程序媛,一位湖南妹子的励志故事

2.如何才能成为优秀的架构师?

3.从零开始搭建创业公司后台技术栈

4.程序员一般可以从什么平台接私活?

5.37岁程序员被裁,120天没找到工作,无奈去小公司,结果懵了...

6.IntelliJ IDEA 2019.3 首个最新访问版本发布,新特性抢先看

7.这封“领导痛批95后下属”的邮件,句句扎心!

8.15张图看懂瞎忙和高效的区别!

浏览 30
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报