[aardio] 扫描文件夹中有GPS信息的照片,然后在地图上定位显示
By
mr_mao
at 2023-11-13 • 0人收藏 • 1163人看过
用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
2023-11-13
#1
高, 这就去下载几个图图试试
登录后方可回帖