[aardio] 扫描文件夹中有GPS信息的照片,然后在地图上定位显示

By mr_mao at 2023-11-13 • 0人收藏 • 800人看过

用aardio做了一个小程序,借助web.view,通过调用一些成熟的js库,实现了获取本地照片exif信息,并根据其中的经纬度定位在地图中。


代码分享给大家,写的比较简单,主要是提供一些思路,aardio是胶水语言,可以借力于web前端的一些框架,做出很漂亮的界面和很新颖的内容,都是很容易的事情。


sshot.jpg


扒了网上一些带点颜色的图片,发现现在年轻人热爱摄影非常会玩,但是提醒大家手机摄影(私拍)时要注意清除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();


下面是基于上面代码编译的小工具:

显示照片拍摄位置的小工具 - 用aardio开发.rar

4 个回复 | 最后更新于 2024-02-19
2023-11-13   #1

高, 这就去下载几个图图试试

2023-11-28   #2

6666666666666

2024-01-16   #3

楼主,我要想象你这样,把多个图片都显示在地图上,该如果处理?

回复#1 @admin :

再来个爬图代码

登录后方可回帖

登 录
信息栏
 私人小站

本站域名

ChengXu.XYZ

投诉联系:  popdes@126.com



快速上位机开发学习,本站主要记录了学习过程中遇到的问题和解决办法及上位机代码分享

这里主要专注于学习交流和经验分享.
纯私人站,当笔记本用的,学到哪写到哪.
如果侵权,联系 Popdes@126.com

友情链接
Aardio官方
Aardio资源网


才仁机械


网站地图SiteMap

Loading...