设为首页收藏本站

 找回密码
 立即注册

只需一步,快速开始

搜索
查看: 136|回复: 11

Windows系统不同语言版本的EXIF属性名称和红米手机的属性存储规则

  [复制链接]
累计签到:15 天
连续签到:1 天
灌水成绩
1
152
1860
主题
帖子
积分

等级头衔

ID : 861

测量学徒

积分成就 测量币 : 1860
在线时间 : 0 小时
注册时间 : 2026-1-21
最后登录 : 2026-5-15

勋章
UID勋章测量学徒测量员
发表于 2026-4-27 08:52:00 来自手机 | 显示全部楼层 |阅读模式 IP:香港
红米机型特殊适配说明:
针对小米/红米的中文EXIF属性名做了专属匹配,兼容"GPS经度"和"经度"两种命名格式
优化了度分秒解析逻辑,适配红米系统使用中文符号「°′″」的存储格式
自动识别中文方向参考("东/西/南/北")和英文参考(E/W/S/N)
使用注意:
确保拍摄时已开启相机的「保存地理位置信息」权限
不要使用微信/QQ等软件传输照片(会自动清除EXIF),建议通过USB或网盘原文件传输
如果仍读取失败,可以右键查看照片属性→详细信息,确认GPS项是否存在数值
需要批量读取文件夹内所有红米照片的GPS并导出到Excel吗?我可以扩展批量处理功能。



  • Option Explicit

  • ' 坐标系转换参数
  • Private Const pi As Double = 3.14159265358979
  • Private Const a As Double = 6378245#
  • Private Const ee As Double = 6.69342162296594E-03

  • ' 红米Note 14 Pro专属GPS读取主程序
  • Sub ReadRedmiPhotoGPS()
  •     Dim imgPath As String
  •     Dim wgsLon As Double, wgsLat As Double
  •     Dim gcjLon As Double, gcjLat As Double

  •     ' 选择照片
  •     With Application.FileDialog(msoFileDialogFilePicker)
  •         .Filters.Clear
  •         .Filters.Add "JPG图片", "*.jpg;*.jpeg"
  •         .Title = "选择红米拍摄的照片"
  •         If .Show  -1 Then Exit Sub
  •         imgPath = .SelectedItems(1)
  •     End With

  •     ' 读取适配红米的GPS数据
  •     If GetRedmiGPS(imgPath, wgsLon, wgsLat) Then
  •         ' 转换为GCJ-02坐标系
  •         WGS84ToGCJ02 wgsLat, wgsLon, gcjLat, gcjLon

  •         ' 输出结果
  •         MsgBox "红米照片坐标(GCJ-02坐标系):" & vbCrLf & _
  •                "经度:" & Format(gcjLon, "0.000000") & vbCrLf & _
  •                "纬度:" & Format(gcjLat, "0.000000"), vbInformation

  •         ' 写入单元格
  •         ActiveCell = Format(gcjLon, "0.000000")
  •         ActiveCell.Offset(0, 1) = Format(gcjLat, "0.000000")
  •     Else
  •         MsgBox "未读取到GPS信息,请确认:" & vbCrLf & _
  •                "1. 照片由红米Note 14 Pro拍摄且已开启定位权限" & vbCrLf & _
  •                "2. 照片未经过压缩/修图软件修改EXIF", vbExclamation
  •     End If
  • End Sub

  • ' 适配小米/红米机型的GPS读取函数
  • Private Function delGetRedmiGPS(imgPath As String, ByRef lon As Double, ByRef lat As Double) As Boolean
  •     Dim shell As Object
  •     Dim folder As Object
  •     Dim file As Object
  •     Dim propName As String, propValue As String
  •     Dim i As Integer
  •     Dim lonRef As String, latRef As String
  •     Dim deg As Double, min As Double, sec As Double

  •     Set shell = CreateObject("Shell.Application")
  •     Set folder = shell.Namespace(Left(imgPath, InStrRev(imgPath, "")))
  •     Set file = folder.ParseName(Right(imgPath, Len(imgPath) - InStrRev(imgPath, "")))

  •     ' 适配红米EXIF属性命名规则
  •     For i = 0 To 300
  •         propName = folder.GetDetailsOf(folder.Items, i)
  •         propValue = folder.GetDetailsOf(file, i)

  •         Select Case Trim(propName)

  •             Case "经度", "GPS经度"
  •             Stop
  •                 If propValue  "" Then
  •                     ' 解析红米的"XX°XX′XX.XX″"格式
  •                     deg = Val(Split(propValue, "°")(0))
  •                     min = Val(Split(Split(propValue, "°")(1), "′")(0)) / 60
  •                     sec = Val(Replace(Split(Split(propValue, "′")(1), "″")(0), ",", ".")) / 3600
  •                     lon = deg + min + sec
  •                 End If
  •             Case "经度参考", "GPS经度参考"
  •                 lonRef = Trim(propValue)
  •             Case "纬度", "GPS纬度"
  •                 If propValue  "" Then
  •                     deg = Val(Split(propValue, "°")(0))
  •                     min = Val(Split(Split(propValue, "°")(1), "′")(0)) / 60
  •                     sec = Val(Replace(Split(Split(propValue, "′")(1), "″")(0), ",", ".")) / 3600
  •                     lat = deg + min + sec
  •                 End If
  •             Case "纬度参考", "GPS纬度参考"
  •                 latRef = Trim(propValue)
  •         End Select
  •     Next i
  •     Stop
  •     ' 处理方向参考
  •     If lon > 0 And lat > 0 Then
  •         If lonRef = "W" Or lonRef = "西" Then lon = -lon
  •         If latRef = "S" Or latRef = "南" Then lat = -lat
  •         GetRedmiGPS = True
  •     Else
  •         GetRedmiGPS = False
  •     End If
  • End Function

  • ' WGS84转GCJ-02核心算法
  • Private Sub WGS84ToGCJ02(wgLat As Double, wgLon As Double, ByRef mgLat As Double, ByRef mgLon As Double)
  •     Dim dLat As Double, dLon As Double
  •     Dim radLat As Double, magic As Double, sqrtMagic As Double

  •     If OutOfChina(wgLat, wgLon) Then
  •         mgLat = wgLat
  •         mgLon = wgLon
  •         Exit Sub
  •     End If

  •     dLat = TransformLat(wgLon - 105, wgLat - 35)
  •     dLon = TransformLon(wgLon - 105, wgLat - 35)
  •     radLat = wgLat / 180 * pi
  •     magic = Sin(radLat)
  •     magic = 1 - ee * magic * magic
  •     sqrtMagic = Sqrt(magic)
  •     dLat = (dLat * 180) / ((a * (1 - ee)) / (magic * sqrtMagic) * pi)
  •     dLon = (dLon * 180) / (a / sqrtMagic * Cos(radLat) * pi)
  •     mgLat = wgLat + dLat
  •     mgLon = wgLon + dLon
  • End Sub

  • ' 中国范围判断
  • Private Function OutOfChina(lat As Double, lon As Double) As Boolean
  •     If lon < 72.004 Or lon > 137.8347 Then
  •         OutOfChina = True
  •     ElseIf lat < 0.8293 Or lat > 55.8271 Then
  •         OutOfChina = True
  •     Else
  •         OutOfChina = False
  •     End If
  • End Function

  • ' 坐标转换辅助函数
  • Private Function TransformLat(x As Double, y As Double) As Double
  •     Dim ret As Double
  •     ret = -100 + 2 * x + 3 * y + 0.2 * y * y + 0.1 * x * y + 0.2 * Sqrt(Abs(x))
  •     ret = ret + (20 * Sin(6 * x * pi) + 20 * Sin(2 * x * pi)) * 2 / 3
  •     ret = ret + (20 * Sin(y * pi) + 40 * Sin(y / 3 * pi)) * 2 / 3
  •     ret = ret + (160 * Sin(y / 12 * pi) + 320 * Sin(y * pi / 30)) * 2 / 3
  •     TransformLat = ret
  • End Function

  • Private Function TransformLon(x As Double, y As Double) As Double
  •     Dim ret As Double
  •     ret = 300 + x + 2 * y + 0.1 * x * x + 0.1 * x * y + 0.1 * Sqrt(Abs(x))
  •     ret = ret + (20 * Sin(6 * x * pi) + 20 * Sin(2 * x * pi)) * 2 / 3
  •     ret = ret + (20 * Sin(x * pi) + 40 * Sin(x / 3 * pi)) * 2 / 3
  •     ret = ret + (150 * Sin(x / 12 * pi) + 300 * Sin(x / 30 * pi)) * 2 / 3
  •     TransformLon = ret
  • End Function

  • ' ========== 修复后的红米GPS读取函数 ==========
  • Private Function GetRedmiGPS(imgPath As String, ByRef lon As Double, ByRef lat As Double) As Boolean
  •     Dim shell As Object
  •     Dim folder As Object
  •     Dim file As Object
  •     Dim propName As String, propValue As String
  •     Dim i As Integer
  •     Dim lonRef As String, latRef As String
  •     Dim deg As Double, min As Double, sec As Double
  •     Dim parts As Variant

  •     Set shell = CreateObject(&quot;Shell.Application&quot;)
  •     Set folder = shell.Namespace(Left(imgPath, InStrRev(imgPath, &quot;&quot;)))
  •     Set file = folder.ParseName(Right(imgPath, Len(imgPath) - InStrRev(imgPath, &quot;&quot;)))

  •     ' 【关键修复1】增加所有可能的属性名匹配,兼容不同系统和机型
  •     For i = 0 To 350
  •         propName = Trim(folder.GetDetailsOf(folder.Items, i))
  •         propValue = Trim(folder.GetDetailsOf(file, i))

  •         ' 调试:输出所有非空属性名和值,可在立即窗口查看
  •         If propValue  &quot;&quot; Then Debug.Print &quot;属性&quot; & i & &quot;: [&quot; & propName & &quot;] = &quot; & propValue

  •         Select Case True
  •             ' 匹配所有可能的经度属性名
  •             Case InStr(1, propName, &quot;经度&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;Longitude&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;GPS经度&quot;, vbTextCompare) > 0
  •                 If propValue  &quot;&quot; Then
  •                     ' 【关键修复2】兼容任意分隔符的度分秒格式
  •                     propValue = Replace(Replace(Replace(propValue, &quot;°&quot;, &quot; &quot;), &quot;′&quot;, &quot; &quot;), &quot;″&quot;, &quot; &quot;)
  •                     propValue = Replace(Replace(propValue, &quot;'&quot;, &quot; &quot;), &quot;&quot;&quot;&quot;, &quot; &quot;)
  •                     parts = Split(WorksheetFunction.Trim(propValue), &quot; &quot;)

  •                     deg = Val(parts(0))
  •                     min = Val(parts(1)) / 60
  •                     sec = Val(Replace(parts(2), &quot;,&quot;, &quot;.&quot;)) / 3600
  •                     lon = deg + min + sec
  •                 End If

  •             ' 匹配所有可能的经度参考属性名
  •             Case InStr(1, propName, &quot;经度参考&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;LongitudeRef&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;经度基准&quot;, vbTextCompare) > 0
  •                 lonRef = UCase(Trim(propValue))

  •             ' 匹配所有可能的纬度属性名
  •             Case InStr(1, propName, &quot;纬度&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;Latitude&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;GPS纬度&quot;, vbTextCompare) > 0
  •                 If propValue  &quot;&quot; Then
  •                     propValue = Replace(Replace(Replace(propValue, &quot;°&quot;, &quot; &quot;), &quot;′&quot;, &quot; &quot;), &quot;″&quot;, &quot; &quot;)
  •                     propValue = Replace(Replace(propValue, &quot;'&quot;, &quot; &quot;), &quot;&quot;&quot;&quot;, &quot; &quot;)
  •                     parts = Split(WorksheetFunction.Trim(propValue), &quot; &quot;)

  •                     deg = Val(parts(0))
  •                     min = Val(parts(1)) / 60
  •                     sec = Val(Replace(parts(2), &quot;,&quot;, &quot;.&quot;)) / 3600
  •                     lat = deg + min + sec
  •                 End If

  •             ' 匹配所有可能的纬度参考属性名
  •             Case InStr(1, propName, &quot;纬度参考&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;LatitudeRef&quot;, vbTextCompare) > 0, _
  •                  InStr(1, propName, &quot;纬度基准&quot;, vbTextCompare) > 0
  •                 latRef = UCase(Trim(propValue))
  •         End Select
  •     Next i

  •     ' 处理方向参考,兼容中英文
  •     If lon > 0 And lat > 0 Then
  •         If lonRef = &quot;W&quot; Or lonRef = &quot;西&quot; Then lon = -lon
  •         If latRef = &quot;S&quot; Or latRef = &quot;南&quot; Then lat = -lat
  •         GetRedmiGPS = True
  •     Else
  •         GetRedmiGPS = False
  •     End If
  • End Function

累计签到:19 天
连续签到:13 天
灌水成绩
2
151
2399
主题
帖子
积分

等级头衔

ID : 803

初级技术员

积分成就 测量币 : 2399
在线时间 : 0 小时
注册时间 : 2026-4-1
最后登录 : 2026-5-22

勋章
UID勋章测量学徒测量员
发表于 2026-4-27 10:59:00 | 显示全部楼层 IP:香港
有点曲高和寡
回复

使用道具 举报

累计签到:21 天
连续签到:7 天
灌水成绩
0
178
13279
主题
帖子
积分

等级头衔

ID : 552

高级技术员

积分成就 测量币 : 13279
在线时间 : 0 小时
注册时间 : 2025-11-11
最后登录 : 2026-5-21

勋章
UID勋章测量学徒测量员
发表于 2026-4-30 21:30:01 | 显示全部楼层 IP:北京
适合自学,不用再到处找资料。
回复

使用道具 举报

累计签到:21 天
连续签到:7 天
灌水成绩
0
178
13279
主题
帖子
积分

等级头衔

ID : 552

高级技术员

积分成就 测量币 : 13279
在线时间 : 0 小时
注册时间 : 2025-11-11
最后登录 : 2026-5-21

勋章
UID勋章测量学徒测量员
发表于 2026-5-1 01:19:47 | 显示全部楼层 IP:广东东莞
适合自学,不用再到处找资料。
回复

使用道具 举报

累计签到:20 天
连续签到:7 天
灌水成绩
0
164
13731
主题
帖子
积分

等级头衔

ID : 539

高级技术员

积分成就 测量币 : 13731
在线时间 : 0 小时
注册时间 : 2026-2-19
最后登录 : 2026-5-22

勋章
UID勋章测量学徒测量员
发表于 2026-5-1 01:21:43 | 显示全部楼层 IP:广东东莞
代码简洁优雅,学到了。
回复

使用道具 举报

累计签到:19 天
连续签到:13 天
灌水成绩
0
146
12167
主题
帖子
积分

等级头衔

ID : 585

高级技术员

积分成就 测量币 : 12167
在线时间 : 0 小时
注册时间 : 2026-1-19
最后登录 : 2026-5-22

勋章
UID勋章测量学徒测量员
发表于 2026-5-1 01:21:43 | 显示全部楼层 IP:广东东莞
内容很全面,几乎覆盖所有场景。
回复

使用道具 举报

累计签到:17 天
连续签到:6 天
灌水成绩
1
171
13310
主题
帖子
积分

等级头衔

ID : 545

高级技术员

积分成就 测量币 : 13310
在线时间 : 0 小时
注册时间 : 2025-12-31
最后登录 : 2026-5-21

勋章
UID勋章测量学徒测量员
发表于 2026-5-1 01:41:59 | 显示全部楼层 IP:广东东莞
对架构思路有很大帮助。
回复

使用道具 举报

累计签到:17 天
连续签到:13 天
灌水成绩
0
133
10646
主题
帖子
积分

等级头衔

ID : 548

高级技术员

积分成就 测量币 : 10646
在线时间 : 0 小时
注册时间 : 2025-12-30
最后登录 : 2026-5-22

勋章
UID勋章测量学徒测量员
发表于 2026-5-1 01:43:51 | 显示全部楼层 IP:广东东莞
实用性极强,强烈推荐。
回复

使用道具 举报

累计签到:17 天
连续签到:1 天
灌水成绩
0
177
13564
主题
帖子
积分

等级头衔

ID : 573

高级技术员

积分成就 测量币 : 13564
在线时间 : 0 小时
注册时间 : 2026-3-8
最后登录 : 2026-5-6

勋章
UID勋章测量学徒测量员
发表于 2026-5-1 01:43:51 | 显示全部楼层 IP:广东东莞
很多技巧平时工作中真的能用。
回复

使用道具 举报

累计签到:18 天
连续签到:7 天
灌水成绩
1
168
13306
主题
帖子
积分

等级头衔

ID : 570

高级技术员

积分成就 测量币 : 13306
在线时间 : 0 小时
注册时间 : 2025-10-20
最后登录 : 2026-5-19

勋章
UID勋章测量学徒测量员
发表于 2026-5-4 11:22:25 | 显示全部楼层 IP:美国
非常良心的技术分享,支持。
回复

使用道具 举报

快速回复换一批
好贴支持!
感谢楼主,好人一生平安
路过留名
马克一下
2333333333
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Archiver|手机版|小黑屋|精密测量技术论坛 ( 桂ICP备2026007449号-1 )|网站地图

GMT+8, 2026-5-23 11:06 , Processed in 0.430779 second(s), 41 queries .

快速回复 返回顶部 返回列表