[aardio] 扫描文件夹中有GPS信息的照片,然后在地图上定位显示
By
mr_mao
at 2023-11-13 • 0人收藏 • 852人看过
用aardio做了一个小程序,借助web.view,通过调用一些成熟的js库,实现了获取本地照片exif信息,并根据其中的经纬度定位在地图中。
代码分享给大家,写的比较简单,主要是提供一些思路,aardio是胶水语言,可以借力于web前端的一些框架,做出很漂亮的界面和很新颖的内容,都是很容易的事情。
扒了网上一些带点颜色的图片,发现现在年轻人热爱摄影非常会玩,但是提醒大家手机摄影(私拍)时要注意清除EXIF信息,不然会泄露隐私的。
代码如下:
import fonts.fontAwesome; import win.ui; /*DSG{{*/ var winform = win.form(text="扫描文件夹中有GPS信息的照片 -毛老师教你学编程";right=1223;bottom=879) winform.add( btnCancle={cls="button";text="取消";left=272;top=16;right=325;bottom=56;dl=1;dt=1;font=LOGFONT(h=-14;name='FontAwesome');z=6}; btnSearch={cls="button";text='\uF115 选择要扫描的文件夹';left=24;top=16;right=269;bottom=56;dl=1;dt=1;font=LOGFONT(h=-14;name='FontAwesome');z=1}; custom={cls="custom";left=592;top=400;right=1200;bottom=856;db=1;dl=1;dr=1;dt=1;edge=1;z=4}; listview={cls="listview";left=24;top=72;right=1200;bottom=392;dl=1;dr=1;dt=1;edge=1;z=2}; plus={cls="plus";left=24;top=400;right=584;bottom=856;db=1;dl=1;dt=1;edge=1;repeat="scale";z=3}; static={cls="static";left=344;top=24;right=1192;bottom=50;transparent=1;z=5} ) /*}}*/ import fsys.dlg.dir; import crypt.bin; //base64 编码 import web.json; import win.cur; import process; import web.view; var wv = web.view(winform.custom) wv.enableDefaultContextMenus(false) wv.enableDevTools(false) //设置listview winform.listview.insertColumn("文件名",230,,0x0/*_LVCFMT_LEFT*/) winform.listview.insertColumn("文件大小",100,,2/*_LVCFMT_CENTER*/) winform.listview.insertColumn("修改时间",130,,2/*_LVCFMT_CENTER*/) winform.listview.insertColumn("经度",110,,0x0/*_LVCFMT_LEFT*/) winform.listview.insertColumn("纬度",110,,0x0/*_LVCFMT_LEFT*/) winform.listview.insertColumn("文件路径",420,,0x0/*_LVCFMT_LEFT*/) winform.listview.adjust = function(cx,cy){ winform.listview.fillParent(6); } winform.listview.fullRow = true; winform.listview.gridLines = true; winform.listview.enableDoubleBuffering(); //先隐藏取消按钮 winform.btnCancle.hide = true var boolStop = false; //用来中止fsys.enum() //webView加载html wv.html = /** <!doctype html> <meta charset="utf-8"> <style type="text/css"> html,body{ height:100%; margin:0; } </style> <link rel="stylesheet" href="https://unpkg.com/leaflet@1.9.4/dist/leaflet.css" crossorigin=""/> <script src="https://unpkg.com/leaflet@1.9.4/dist/leaflet.js" crossorigin=""></script> <script src="https://aardio.online/attach-download-173.htm"></script> <div id="map" style="width: 100vw; height: 100vh;"></div> <script> //获取图像的经纬度 window.getGPS = function(base64String){ let binDatas = atob(base64String); let bytes = new Uint8Array(binDatas.length); for (let i=0; i<binDatas.length; i++) { bytes[i] = binDatas.charCodeAt(i); } var buf = bytes.buffer; if(document.readyState=="complete"){ var tags = ExifReader.load(buf, {expanded: true}); if(tags.exif.GPSLatitude ){ let GPSLatitude = tags.exif.GPSLatitude.description; let GPSLongitude = tags.exif.GPSLongitude.description; buf = null bytes = null var o = {"lat": GPSLatitude, "lng": GPSLongitude}; return JSON.stringify(o); } } } //初始化地图 let thislat = 34.1925651; let thislng = 108.858193; var latLng = L.latLng(thislat,thislng); //设置地图中心点 const map = L.map('map',{zoomControl:false,attributionControl:false}).setView(latLng, 12); //设置瓦片(国外tile网站有免费api-key,但加载比较慢) var tileUrl = 'https://tile.thunderforest.com/atlas/{z}/{x}/{y}.png?apikey=54d8ea9ecff141339879bee89f3dd354' const tiles = L.tileLayer(tileUrl, { maxZoom: 19, attribution: false, }).addTo(map); let marker; //定位到指定的位置 window.locate = function(jsonLatlng,thumbBase64){ if(marker) map.removeLayer(marker) //先清空marker var obj = JSON.parse(jsonLatlng) var position = [obj.lat, obj.lng] map.panTo(position); setTimeout(function() { var thumbnaildatas = "data:image/png;base64," + thumbBase64 var imgcontrol = `<img src=` + thumbnaildatas; imgcontrol +=` width=100 height=80/>` marker = new L.Marker(position); map.addLayer(marker); marker.bindPopup(imgcontrol) .openPopup(); },1000) } window.onChangeSize = function () { map.invalidateSize(true); } </script> **/ //深度扫描指定文件夹(包括子目录) winform.btnSearch.oncommand = function(id,event){ var dirpath = fsys.dlg.dir() if(dirpath){ //界面变化 winform.listview.clear(); winform.plus.background = null wv.doScript("if(marker) map.removeLayer(marker)") winform.btnSearch.disabledText = {'\uF250';'\uF251';'\uF252';'\uF253';'\uF254';text="正在扫描..."} winform.btnCancle.hide = false; win.cur.beginWaitCur() boolStop = false; var totalnum, oknum = 0, 0; fsys.enum( dirpath, {"*.jpg";"*.png"}, function(dir,filename,fullpath,findData){ if(filename){ totalnum++; winform.static.text = "正在扫描:" + fullpath var datas = string.load( fullpath ); var base64Datas = crypt.bin.encodeBase64(datas) var ret = wv.xcall("getGPS", base64Datas); //返回经纬度 if(ret){ oknum++; var gps = web.json.parse(ret) var lng = gps.lng; var lat = gps.lat; var size = math.size64(findData.nFileSizeLow,findData.nFileSizeHigh).format() var tm = time( fsys.fromFileTime(findData.ftLastWriteTime)); tm.addhour(8) var mdftime = tostring(tm,"%Y-%m-%d %H:%M:%S");//本地时间 //显示在listview中 winform.listview.addItem({filename, size, mdftime, lng, lat, fullpath}) } win.peekPumpMessage(1) }; if(boolStop==true) return false; //返回false停止 } ,true/*包括子目录*/ ); winform.static.text = "已扫描 " + totalnum + " 个文件, 找到 " + oknum + " 个含GPS信息的图片." //界面恢复 win.cur.endCur() winform.btnSearch.disabledText = null winform.btnCancle.hide = true } } //单击listview行,预览并定位 winform.listview.onnotify = function(id,code,ptr){ select(code) { case 0xFFFFFFFE/*_NM_CLICK*/ { var nm = owner.getNotifyMessage(code,ptr) if(nm.iItem){ var filepath = owner.getItemText(,6) winform.plus.background = filepath var lat, lng = owner.getItemText(,5), owner.getItemText(,4) var latlng = web.json.stringify({"lat"=lat;"lng"=lng}) var thumbnailDatas = winform.plus.background.getThumbnail(100,80).saveToBuffer() //缩略图 var base64thumb = crypt.bin.encodeBase64( thumbnailDatas ) //在地图中定位 wv.invoke("locate", latlng, base64thumb); } } } } //双击listview行在资源管理器打开图片 winform.listview.onDoubleClick = function(item,subItem,nmListView){ if(item) process.explore_select( winform.listview.getItemText(item,6) ) } //暂停扫描 winform.btnCancle.oncommand = function(id,event){ boolStop = true; } winform.show(); win.loopMessage();
下面是基于上面代码编译的小工具:
4 个回复 | 最后更新于 2024-02-19
![admin](/upload/avatar/middle/1.png)
admin
2023-11-13
#1
高, 这就去下载几个图图试试
登录后方可回帖