使用数码相机或者手机拍摄的jpg照片,一般都包含了EXIF信息(小米手机肯定有这些信息,其它手机不一定有),即拍摄时所使用的光圈、快门、经纬度等数据。下面就介绍如何获取这些信息。
新建一个窗体,添加一个按纽,一个文本框(设置为:可接受多行、有垂直和水平滚动条),代码如下。

Option Explicit

Private Type PropertyItem '标签结构
  propId As Long  '标签ID
  Length As Long  '标签值长度字节
  Type   As Long  '标签类型
  Value  As Long  '标签值
End Type

Private Type GdiplusStartupInput
  GdiplusVersion As Long
  DebugEventCallback As Long
  SuppressBackgroundThread As Long
  SuppressExternalCodecs As Long
End Type

Private Declare Function GdiplusStartup Lib "gdiplus.dll" (ByRef Token As Long, ByRef inputX As GdiplusStartupInput, Optional ByVal outputbuf As Long = 0) As Long
Private Declare Function GdipLoadImageFromFile Lib "gdiplus" (ByVal FileName As Long, ByRef Image As Long) As Long
Private Declare Function GdipGetPropertyCount Lib "gdiplus" (ByVal Image As Long, numOfProperty As Long) As Long
Private Declare Function GdipGetPropertyIdList Lib "gdiplus" (ByVal Image As Long, ByVal numOfProperty As Long, list As Long) As Long
Private Declare Function GdipGetPropertyItemSize Lib "gdiplus" (ByVal Image As Long, ByVal propId As Long, Size As Long) As Long
Private Declare Function GdipGetPropertyItem Lib "gdiplus" (ByVal Image As Long, ByVal propId As Long, ByVal propSize As Long, buffer As Long) As Long
Private Declare Function GdipDisposeImage Lib "gdiplus" (ByVal Image As Long) As Long
Private Declare Function GdiplusShutdown Lib "gdiplus.dll" (ByVal Token As Long) As Long
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (pDst As Any, pSrc As Any, ByVal ByteLen As Long)

Private Sub Command1_Click()
Text1 = AccessEXIF("100.jpg") '这里是全路径文件名,必须是jpg文件
End Sub

Private Function AccessEXIF(openName As String) As String
Dim Bitmap        As Long    '图像句柄
Dim Token         As Long    'Gdip启动标记
Dim Index         As Long    '标签索引
Dim PropertyCount As Long    '标签数量
Dim ItemSize      As Long    '标签值大小
Dim TagName       As String  '标签名
Dim TagID         As String * 4 '标签ID
Dim udtData As GdiplusStartupInput
Dim Prop          As PropertyItem
Dim d5 As String, st1 As String, st2 As String, st3 As String, st4 As String, st5 As String
Dim d_1 As Long, d_2 As Long
Dim k As Integer, Z As String

udtData.GdiplusVersion = 1
GdiplusStartup Token, udtData                  '启动Gdip
GdipLoadImageFromFile StrPtr(openName), Bitmap '装入图像,获取图像句柄
GdipGetPropertyCount Bitmap, PropertyCount     '获取标签数量

If PropertyCount Then
  ReDim PropertyList(PropertyCount - 1) As Long
  GdipGetPropertyIdList Bitmap, PropertyCount, PropertyList(0)    '获取所有标签的ID(TagID)

  For Index = 0 To PropertyCount - 1
    GdipGetPropertyItemSize Bitmap, PropertyList(Index), ItemSize '获取标签大小
    ReDim buffer(ItemSize - 1) As Byte                            '根据标签大小建立缓冲区
    GdipGetPropertyItem Bitmap, PropertyList(Index), ItemSize, ByVal VarPtr(buffer(0)) '根据标签大小获取其内容
    CopyMemory Prop, ByVal VarPtr(buffer(0)), Len(Prop) '把标签内容复制到Prop结构
    ReDim Data(ItemSize - 1) As Byte
    CopyMemory Data(0), ByVal Prop.Value, ItemSize - 1  '把Prop结构中的标签值复制到Data数组
    TagID = Right("000" & Hex(Prop.propId), 4)
    TagName = "": Z = "": d_1 = 0: d_2 = 0

    Select Case Prop.Type
      Case 1 '值类型是字节
        Select Case TagID
          Case "A301": TagName = "场景拍摄类型.:": Z = IIf(Data(0) = 1, "图像是数码设备拍摄的", "未知")
          Case "8773": TagName = "图像颜色位深.:": Z = IIf(Data(0) = 0, "24位真彩", "未知")
        End Select
        If Len(TagName) Then st1 = st1 & TagName & Z & vbCrLf
      
      Case 2, 7 '值类型是文本
        Select Case TagID
          Case "001B": TagName = "定位方式...:": If Data(0) <> 0 And Data(1) = 0 And Data(2) <> 0 And Data(3) = 0 And Data(4) <> 0 Then Data(1) = Data(2): Data(2) = Data(4) '如果是unicode字符
          Case "001D": TagName = "拍摄日期...:"
          Case "0131": TagName = "图像生成软件.:"
          Case "0132": TagName = "图像生成时间.:"
          Case "5041": TagName = "Interop 索引.:"
          Case "5042": TagName = "Interop 版本.:"
          Case "010E": TagName = "图像描述...:"
          Case "010F": TagName = "相机制造厂商.:"
          Case "0110": TagName = "数码相机型号.:"
          Case "5026": TagName = "设备制造商..:"
          Case "5027": TagName = "设备型号...:"
          Case "5033": TagName = "设备使用时间.:"
          Case "8824": TagName = "光谱敏感度..:"
          Case "8889": TagName = "高动态范围技术:"
          Case "9000": TagName = "Exif版本...:"
          Case "9003": TagName = "照片拍摄时间.:"
          Case "9004": TagName = "数字化时间..:"
          Case "9010": TagName = "经度所在时区.:"
          Case "9011": TagName = "纬度所在时区.:"
          Case "9012": TagName = "高度所在时区.:"
          Case "9101": TagName = "像素顺序...:": Z = IIf(Data(0) = 1 And Data(1) = 2 And Data(2) = 3, "YCbCr", "RGB"): Data = StrConv(Z, vbFromUnicode)
          Case "927C": TagName = "厂商注释...:"
          Case "9286": TagName = "用户注释...:"
          Case "9290": TagName = "拍摄时间(微秒):"
          Case "9291": TagName = "初始时间(微秒):"
          Case "9292": TagName = "数化时间(微秒):"
          Case "9A00": TagName = "拍摄设备...:"
          Case "A000": TagName = "FlashPix版本.:"
          Case "A300": TagName = "图像来源...:": Z = IIf(Data(0) = 3, "数字相机", "未知"): Data = StrConv(Z, vbFromUnicode)
          Case "C4A5": TagName = "打印命令集版本:"
        End Select
        If Len(TagName) Then
          Z = StrConv(Data, vbUnicode): k = InStr(Z, Chr(0)): If k Then Z = Left(Z, k - 1)
          st2 = st2 & TagName & Z & vbCrLf
        End If
      
      Case 3  '值类型是整形
        Select Case TagID
          Case "0103": TagName = "数据压缩方式.:": Z = IIf(Data(0) = 0, "未压缩", "JPEG压缩")
          Case "0213": TagName = "颜色抽样方式.:": Z = IIf(Data(0) = 1, "像素阵列中心", "基准点")
          Case "8827": TagName = "ISO 感光度速率:": Z = Data(0) + CLng(Data(1)) * 256
          Case "9208": TagName = "光源.....:": GoSub 9208
          Case "9209": TagName = "闪光灯状态..:": GoSub 9209
          Case "A001": TagName = "色彩空间...:": Z = IIf(Data(0) = 1, "sRGB", "其它")
          Case "A405": TagName = "35mm机等效焦距:": Z = Data(0) & "mm": If Data(0) = 0 Then Z = "未知"
          Case Else
            If Data(0) > 9 Then Data(0) = 0
            Select Case TagID
              Case "0128": TagName = "像素密度单位.:": Z = Choose(Data(0) + 1, "未知", "无单位", "英吋", "厘米")
              Case "8822": TagName = "曝光模式...:": Z = Choose(Data(0) + 1, "自动", "手动曝光", "正常曝光", "光圈优先", "快门优先", "慢速", "高速", "肖像", "风景")
              Case "9207": TagName = "测光模式...:": Z = Choose(Data(0) + 1, "自动", "平均测光", "中央重点测光", "点测光", "多点测光", "多区域测光", "部分测光", "其它")
              Case "A210": TagName = "像素密度单位.:": Z = Choose(Data(0) + 1, "未知", "无单位", "英吋", "厘米")
              Case "A217": TagName = "图像传感器类型:": Z = Choose(Data(0) + 1, "未知", "未定义", "单片彩色区域感应器", "单片彩色线性感应器", "三片彩色区域感应器", "三片彩色线性感应器", "未知", "彩色顺序区域感应器", "彩色顺序线性感应器", "未知")
              Case "A403": TagName = "白平衡....:": Z = Choose(Data(0) + 1, "自动", "日光", "荧光灯", "白炽灯", "其它")
              Case "A406": TagName = "场景类型...:": Z = Choose(Data(0) + 1, "标准", "风景", "人像", "夜景")
              Case "A408": TagName = "对比度....:": Z = Choose(Data(0) + 1, "正常", "低", "高")
              Case "A409": TagName = "饱和度....:": Z = Choose(Data(0) + 1, "正常", "低", "高")
              Case "A40A": TagName = "锐化度....:": Z = Choose(Data(0) + 1, "正常", "低", "高")
            End Select
        End Select
        If Len(TagName) Then st3 = st3 & TagName & Z & vbCrLf
      
      Case 4  '值类型是长整形
        Select Case TagID
          Case "0100": TagName = "图像宽度(像素):"
          Case "0101": TagName = "图像高度(像素):"
          Case "0112": TagName = "相机对场景方向:"
          Case "0201": TagName = "缩略图的偏移量:"
          Case "0202": TagName = "缩略图占用字节:"
          Case "8825": TagName = "位置信息(GPS) :"
          Case "8833": TagName = "感光度(ISO)..:"
          Case "9208": TagName = "白平衡....:"
          Case "A002": TagName = "源图像宽(像素):"
          Case "A003": TagName = "源图像高(像素):"
          Case "9206": TagName = "到对象距离(米):"
        End Select
        If Len(TagName) Then
          Select Case TagID
            Case "0112": Z = Choose(Data(3) + 1, "自动", "顶部左侧", "顶部右侧", "底部右侧", "底部左侧", "左侧顶部", "右侧顶部", "右侧底部", "左侧底部")
            Case "9208": GoSub 9208
            Case Else: Z = CLng(Data(2)) * 65536 + CLng(Data(1)) * 256 + Data(0)
          End Select
          st4 = st4 & TagName & Z & vbCrLf
        End If
      
      Case 5, 10 '值类型是分数
        Select Case TagID
          Case "0002": TagName = "纬度.....:": Z = Data(0) & "度" & Data(8) & "分"
          Case "0004": TagName = "经度.....:": Z = Data(0) & "度" & Data(8) & "分"
          Case "0006": TagName = "海拔.....:": Dim myLong1 As Long, myLong2 As Long: myLong1 = CLng(Data(2)) * 65536 + CLng(Data(1)) * 256 + Data(0): myLong2 = CLng(Data(6)) * 65536 + CLng(Data(5)) * 256 + Data(4): If myLong2 Then Z = myLong1 / myLong2 & "米"
          Case "011A": TagName = "水平像素密度.:": GoSub 500: Z = d5
          Case "011B": TagName = "垂直像素密度.:": GoSub 500: Z = d5
          Case "829A": TagName = "曝光时间(秒).:": GoSub 500: Z = "1/" & Round(1 / d5, 0)
          Case "829D": TagName = "光圈大小(F值).:": GoSub 500: Z = "F" & Format(d5, "0.0")
          Case "9201": TagName = "快门速度(秒).:": GoSub 500: Z = "1/" & Format(d5, "#")
          Case "9202": TagName = "相机光圈(F值).:": GoSub 500: Z = "F" & Format(d5, "0.0")
          Case "9203": TagName = "曝光量(亮度).:": GoSub 500: Z = Format(d5 / 10, "0.0")
          Case "9204": TagName = "曝光补偿(EV).:": GoSub 500: Z = Format(d5 / 10, "0.0")
          Case "9205": TagName = "镜头最大光圈值:": GoSub 500: Z = "F" & Format(d5, "0.0")
          Case "920A": TagName = "物理焦距(毫米):": GoSub 500: Z = Format(d5, "0.0")
          Case "A215": TagName = "CCD 感光度..:": GoSub 500: Z = Format(d5, "#")
        End Select
        If Len(TagName) Then st5 = st5 & TagName & Z & vbCrLf
    
    End Select
  Next
  AccessEXIF = st4 & st2 & st5 & st3 & st1
End If

GdipDisposeImage Bitmap
GdiplusShutdown Token
Exit Function

500
d_1 = "&H" & Right("0" & Hex(Data(3)), 2) & Right("0" & Hex(Data(2)), 2) & Right("0" & Hex(Data(1)), 2) & Right("0" & Hex(Data(0)), 2)
d_2 = "&H" & Right("0" & Hex(Data(7)), 2) & Right("0" & Hex(Data(6)), 2) & Right("0" & Hex(Data(5)), 2) & Right("0" & Hex(Data(4)), 2)
If d_2 Then d5 = d_1 / d_2 * IIf(Prop.Type = 5, 1, 10)
Return

9208
Select Case Data(0)
  Case 0: Z = "自动"
  Case 1: Z = "日光"
  Case 2: Z = "荧光灯"
  Case 3: Z = "白炽灯"
  Case 4: Z = "闪光灯"
  Case 9: Z = "晴天"
  Case 10: Z = "阴天"
  Case 11: Z = "阴影"
  Case 12: Z = "日光荧光灯"
  Case 13: Z = "冷白荧光灯"
  Case 14: Z = "白色荧光灯"
  Case 15: Z = "暖白荧光灯"
  Case 17: Z = "标准光A"
  Case 18: Z = "标准光B"
  Case 19: Z = "标准光C"
  Case 20: Z = "D55"
  Case 21: Z = "D65"
  Case 22: Z = "D75"
  Case Else: Z = "其它"
End Select
Return

9209
Select Case Data(0)
  Case 0: Z = "未闪光"
  Case 1: Z = "闪光"
  Case 5: Z = "闪光但未检测反射光"
  Case 7: Z = "闪光且检测了反射光"
  Case Else: Z = "无闪光灯"
End Select
Return
End Function


说明:
1.有个别信息的名称和内容相同,这是因为不同的厂商可以自定义 TagID。
2.以上信息在一张照片中只会具有其中的一部分。