Java中如何根据照片定位你的位置
2021/7/14 12:35:26
本文主要是介绍Java中如何根据照片定位你的位置,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
前言
这篇文章很早之前就想写的,奈何本人比较懒 。本周三在朋友圈看到一位名为Lex Python大佬发表过关于这方面的文章,也因为最近思想上有了很深的觉悟,总想记录一些走过的路。与其说些写技术博客,我更倾向于记录知识。
本文没有什么过深的东西,很简单的小知识,适用各行业的同学们。各位看官看看即可,增加一下安全和隐私意识,虽说互联网时代没有隐私可言,但是可以通过一些操作来避免。接下来说一下作死小能手约翰·迈克菲,通过他的故事知道安全和隐私的重要性。
杀毒软件之父“约翰·迈克菲”的传奇人生!
约翰·迈克菲传奇的一生在2021年6月29日落下了帷幕,但是关于他的作死事迹至今还在流传。下面我简略的说一下,详细的情况我们可以找度娘咨询一下。
20世纪60年代末,他在麦卡菲在一家公司中学会了有关早期计算机的基本知识。在38岁之前不务正业,与毒品和酒精为伴。经历过一些打击,迈克菲痛定思痛戒毒,痛改前非,老老实实的当起程序员。
在这个阶段通过他的技术和头脑,发明了全球第一款商用的杀毒软件McAfee,最开始是免费,因为挣不到钱。靠着自己手段和歪招,娶白富美,当上总经理、出任CEO走上人生巅峰。也许生活的太安逸舒适,追求刺激,玩上各种极限危险运动,结果一次意外自己侄子摔死了。
他最有名的一次作死是在2012年——因涉嫌谋杀遭到中美洲小国伯利兹的通缉。 当时迈克菲大爷正在伯利兹一个小镇上当着土皇帝。他买下了一大片土地,在那儿和7个妹子住一起鬼混。不仅如此,他甚至还花钱把当地警察收编成了私人部队。伯利兹政府怀疑他在偷偷制造冰毒,曾派特种部队突袭过他家,但却没找到违禁药物。
就在这节骨眼上,迈克菲大爷的邻居被枪杀了。伯利兹政府说他有重大杀人嫌疑,而迈克菲大爷则说自己遭到了陷害。 当警方上门逮捕他的时候,迈克菲大爷在后院沙滩上挖了个坑把自己埋进去躲过了搜查。随后他带着女朋友坐小船逃到了邻国危地马拉。
就在这么狼狈的时候,迈克菲大爷也没忘记作死。他不仅发博客嘲笑伯利兹政府,还找来了记者和自己一起体验流亡生活。 没想到那记者是个猪队友,他不但把跟迈克菲大爷的合照发到网上,还说“大家快看,迈克菲和我在一起噢!”(一边逃亡一边浪),
网友们一查照片信息,发现里面居然连GPS定位数据都有。数据显示拍照的地点就在危地马拉的一处海边。 警察闻讯赶过去一搜,发现迈克菲大爷果然躲在那里,于是就把他抓了起来。(好家伙,直呼网友内行啊)
复盘一下约翰·迈克菲如何被抓的?
约翰·迈克菲的故事告诉我们两件事 ,第一件事不作不会死,远离猪队友。第二件事本文正题消除掉Exif信息。
为什么通过一张照片就可以定位到拍照者的准确位置,其实关键在于照片文件里有一个名叫EXIF信息。他其实专门为数码相机照片设计的。用于记录照片的属性和拍摄数据。下面通过代码(技术手段)展示一下EXIF信息!!!
先说配置部分,用Java控制台工程即可,我用的AS控制台工程,建议用IntelliJ IDEA。我是为了省事有现成的编译器就没有用IntelliJ IDEA。我用的是gradle方式作为远程依赖,maven同理。
我熟悉gradle依赖方式,看文档好像metadata-extractor-2.16.0只支持maven,于是把开源项目clone 下来编译成jar放在lib下作为依赖。xmpcore:6.0.6和metadata是配套的需要远程依赖,http请求api方面用的成熟的第三方框架okhttp3。依赖如下图所示:
package com.example.exif; import com.drew.imaging.ImageMetadataReader; import com.drew.metadata.Directory; import com.drew.metadata.Metadata; import com.drew.metadata.Tag; import java.io.File; import java.io.IOException; import okhttp3.Call; import okhttp3.Callback; import okhttp3.OkHttpClient; import okhttp3.Request; import okhttp3.Response; public class ReadExifPhoto { public static void main(String[] args) { File file = new File("/Users/sky/Downloads/IMG_20210706_172959.jpg"); try { Metadata metadata = ImageMetadataReader.readMetadata(file); for (Directory directory : metadata.getDirectories()) { for (Tag tag : directory.getTags()) { System.out.print(tag.getTagName() + " --> "); System.out.println(tag.getDescription()); } if (directory.hasErrors()) { for (String error : directory.getErrors()) { System.err.println("ERROR: " + error); } } } } catch (Exception e) { e.printStackTrace(); } }
控制台输出信息如下内容,我对关键的信息加上注释。详细的每一条属性需要找一下度娘了,我也记不住属性很多!!!
> Task :lib:ReadExifPhoto.main() Compression Type --> Baseline Data Precision --> 8 bits Image Height --> 3472 pixels //图片高度 单位(px) Image Width --> 4624 pixels //图片宽度 单位(px) Number of Components --> 3 Component 1 --> Y component: Quantization table 0, Sampling factors 2 horiz/2 vert Component 2 --> Cb component: Quantization table 1, Sampling factors 1 horiz/1 vert Component 3 --> Cr component: Quantization table 1, Sampling factors 1 horiz/1 vert Version --> 1.1 Resolution Units --> none X Resolution --> 1 dot Y Resolution --> 1 dot Thumbnail Width Pixels --> 0 Thumbnail Height Pixels --> 0 Image Width --> 4624 pixels Model --> Redmi Note 8 Pro //拍摄手机型号 Image Height --> 3472 pixels Orientation --> Right side, top (Rotate 90 CW) Date/Time --> 2021:07:06 17:30:00 //拍摄照片时间 Make --> Xiaomi //拍摄手机厂商 ,小米手机 F-Number --> f/1.9 Focal Length --> 5.4 mm Exposure Time --> 9999/500000 sec Flash --> Flash did not fire Unknown tag (0x9999) --> {"mirror":false,"sensor_type":"rear","Hdr":"auto","OpMode":36869} ISO Speed Ratings --> 396 Unknown tag (0x8895) --> 0 Exif Image Height --> 3472 pixels Exif Image Width --> 4624 pixels Aperture Value --> f/1.9 Shutter Speed Value --> 49.5 sec Sub-Sec Time --> 549 GPS Latitude Ref --> N //北纬 GPS Latitude --> 39° 58' 31.89" //纬度 GPS Longitude Ref --> E //东经 GPS Longitude --> 116° 20' 42.77" //经度 GPS Time-Stamp --> 09:29:59.000 UTC GPS Date Stamp --> 2021:07:06 XMP Value Count --> 1 Number of Tables --> 4 Huffman tables Detected File Type Name --> JPEG //图片类型 Detected File Type Long Name --> Joint Photographic Experts Group Detected MIME Type --> image/jpeg Expected File Name Extension --> jpg File Name --> IMG_20210706_172959.jpg //拍摄图片文件名 File Size --> 6556702 bytes //图片文件大小 转换一下大约6.6mb File Modified Date --> 星期二 七月 06 17:30:46 +08:00 2021
从上面可以获取到关键一点GPS定位信息,从控制台得知E116° 20’ 42.77,N 39° 58’ 31.89, 这个信息是不能直接被使用,需要进行一次转换才能找到真正位置信息。
在数学中,表示角度的度、分、秒分别使用°、′、″符号进行表示。1°=60′,1′=60″ ,1°=3600″。下面的转换工具代码如下:
/** * 经纬度坐标格式转换 * @param Gps */ private static double conversionUtil(String Gps) { String du = Gps.split("°")[0].replace(" ", ""); String fen = Gps.split("°")[1].split("'")[0].replace(" ", ""); String miao = Gps.split("°")[1].split("'")[1].replace(" ", "").replace("\"", ""); return Double.parseDouble(du)+Double.parseDouble(fen)/60 + Double.parseDouble(miao)/3600; } System.out.println("得到的纬度数据为:====="+conversionUtil("39° 58' 31.89")); System.out.println("得到的经度数据为:====="+conversionUtil("116° 20' 42.77")); Console log 输出: 得到的纬度数据为:=====39.975525000000005 得到的经度数据为:=====116.34521388888888
得到了真实的gps定位地址,接下来应该去百度地图或者高德地图找到详细的地理信息。这里我才用的是高德开放平台逆地理web api方式 ,详细调用高德api 需要看下文档,文档内容如下:地理/逆地理编码-API文档-开发指南-Web服务 API | 高德地图API
//演示代码如下,高德key是我自己申请的 ,大家拿去用真实有效。 //也可以用自己申请后的参数。请求上限每天600次,谨慎使用 private static void sendGetRequest(){ String url = "http://restapi.amap.com/v3/geocode/regeo?key=adbda67c40bbe332e1d18b5ddb03d721&location=116.345214,39.975525&radius=500&extensions=base&batch=false&roadlevel=1"; OkHttpClient okHttpClient = new OkHttpClient(); final Request request = new Request.Builder() .url(url) .get()//默认就是GET请求,可以不写 .build(); Call call = okHttpClient.newCall(request); call.enqueue(new Callback() { @Override public void onFailure(Call call, IOException exception) { System.err.println(exception); } @Override public void onResponse(Call call, Response response) throws IOException { System.out.println( "onResponse: " + response.body().string()); } }); }
formatted_address字段就是根据gps得到有效地址信息了。因为计算方式略有不同,我的真实的地址和高德给的略有差异。所以你还是找不到我(手动滑稽)!!!! 代码内容到此结束
{ "status": "1", "regeocode": { "addressComponent": { "city": [], "province": "北京市", "adcode": "110108", "district": "海淀区", "towncode": "110108008000", "streetNumber": { "number": "22号", "location": "116.344753,39.975785", "direction": "西北", "distance": "48.7649", "street": "知春路" }, "country": "中国", "township": "北太平庄街道", "businessAreas": [{ "location": "116.339877,39.965569", "name": "大钟寺村", "id": "110108" }], "building": { "name": [], "type": [] }, "neighborhood": { "name": [], "type": [] }, "citycode": "010" }, "formatted_address": "北京市海淀区北太平庄街道知春路22号知春路22号院" }, "info": "OK", "infocode": "10000" }
你的位置是怎么泄露的呢?
满足以下三个条件就会泄露位置:
-
打开手机GPS定位
-
拍照设置成保存地理位置
-
拍照后发送原图。因此如果我们对症下药注意这几个方面,照片的信息安全会大大提高。
如何防范这个问题呢
只要对图片经过压缩,用PS修改等操作后,该图片的EXIF信息可能就不存在了。朋友圈我们经常用,一般情况下腾讯会对微信朋友圈、公众号的推文里的图片进行压缩,保护个人隐私。建议朋友圈不要发原图!!! 小姐姐们一点也不担心因为你们都是美美的,完全不用担心图片exif信息泄露。
- 安卓系统:以小米手机为例,进入相机设置–关闭保存地理位置信息(开口一句国粹,好像我的保存地理位置信息一直都没关过,我好方 (~ ̄(OO) ̄)ブ)
- 苹果IOS系统:隐私权–定位服务–相机(永不)
提醒
-
不认识的人坚决不提供任何缘由的高清原图,防止获取你的位置信息
-
发布教程、攻略、贴吧的图片应稍加处理再发布
-
不对我国军事等敏感信息等以任何形势提供拍摄(例如铁路线上运送军事武器等)
结尾
有一次妹子问我,你怎么知道我在那个位置 ,现在你应该知道了吧 ,希望你看不到!!!
这篇关于Java中如何根据照片定位你的位置的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-16使用vue3+springboot构建简单Web应用教程
- 2024-11-15全栈开发项目实战:从入门到初级项目的实现
- 2024-11-15数据库项目实战:从入门到初级应用教程
- 2024-11-15IDEA项目实战入门教程
- 2024-11-15IT编程项目实战:新手入门的全面指南
- 2024-11-15Java开发项目实战:新手入门与初级技巧
- 2024-11-15Java零基础项目实战:从入门到独立开发
- 2024-11-15MyBatis Plus教程:入门与基础操作详解
- 2024-11-15MyBatis-Plus教程:新手入门与实战技巧
- 2024-11-15MyBatis教程:从入门到实践