ASP读取JPG图像Exif信息类

<%
const IFD_IDX_Tag_No = 0
const IFD_IDX_Tag_Name = 1
const IFD_IDX_Data_Format = 2
const IFD_IDX_Components = 3
const IFD_IDX_Value = 4
const IFD_IDX_Value_Desc = 5
const IFD_IDX_OffsetToValue = 6

Class Cls_Exif
    Private ExifLookup
    Private Offset_to_IFD0
    Private Offset_to_APP1
    Private Offset_to_TIFF
    Private Length_of_APP1
    Private Offset_to_Next_IFD
    Private IFDDirectory
    Private Offset_to_ExifSubIFD
    Private ImageFileName
    Private IsLoaded
    Private ExifTemp

    Private Sub Class_Initialize()
        Set ExifLookup = Server.CreateObject("Scripting.Dictionary")
        'IFD0 Tags
        ExifLookup.Add "Image Description", "010E"
        ExifLookup.Add "Camera Make", "010F"
        ExifLookup.Add "Camera Model", "0110"
        ExifLookup.Add "Orientation", "0112"
        ExifLookup.Add "X Resolution", "011A"
        ExifLookup.Add "Y Resolution", "011B"
        ExifLookup.Add "Resolution Unit", "0128"
        ExifLookup.Add "Software", "0131"
        ExifLookup.Add "Date Time", "0132"
        ExifLookup.Add "White Point", "013E"
        ExifLookup.Add "Primary Chromaticities", "013F"
        ExifLookup.Add "YCbCr Coefficients", "0211"
        ExifLookup.Add "YCbCr Positioning", "0213"
        ExifLookup.Add "Reference Black White", "0214"
        ExifLookup.Add "Copyright", "8298"
        ExifLookup.Add "Exif Offset", "8769"
        'ExifSubIFD Tags
        ExifLookup.Add "Exposure Time", "829A"
        ExifLookup.Add "FStop", "829D"
        ExifLookup.Add "Exposure Program", "8822"
        ExifLookup.Add "ISO Speed Ratings", "8827"
        ExifLookup.Add "Exif Version", "9000"
        ExifLookup.Add "Date Time original", "9003"
        ExifLookup.Add "Date Time Digitized", "9004"
        ExifLookup.Add "Components Configuration", "9101"
        ExifLookup.Add "Compressed Bits Per Pixel", "9102"
        ExifLookup.Add "Shutter Speed Value", "9201"
        ExifLookup.Add "Aperture Value", "9202"
        ExifLookup.Add "Brightness Value", "9203"
        ExifLookup.Add "Exposure Bias Value", "9204"
        ExifLookup.Add "Max Aperture Value", "9205"
        ExifLookup.Add "Subject Distance", "9206"
        ExifLookup.Add "Metering Mode", "9207"
        ExifLookup.Add "Light Source", "9208"
        ExifLookup.Add "Flash", "9209"
        ExifLookup.Add "Focal Length", "920A"
        ExifLookup.Add "Maker Note", "927C"
        ExifLookup.Add "User Comment", "9286"
        ExifLookup.Add "Subsec Time", "9290"
        ExifLookup.Add "Subsec Time original", "9291"
        ExifLookup.Add "Subsec Time Digitized", "9292"
        ExifLookup.Add "Flash Pix Version", "A000"
        ExifLookup.Add "Color Space", "A001"
        ExifLookup.Add "Exif Image Width", "A002"
        ExifLookup.Add "Exif Image Height", "A003"
        ExifLookup.Add "Related Sound File", "A004"
        ExifLookup.Add "Exif Interoperability Offset", "A005"
        ExifLookup.Add "Focal Plane X Resolution", "A20E"
        ExifLookup.Add "Focal Plane Y Resolution", "A20F"
        ExifLookup.Add "Focal Plane Resolution Unit", "A210"
        ExifLookup.Add "Exposure Index", "A215"
        ExifLookup.Add "Sensing Method", "A217"
        ExifLookup.Add "File Source", "A300"
        ExifLookup.Add "Scene Type", "A301"
        ExifLookup.Add "CFA Pattern", "A302"
        'GPS IFD Tags 2010-01-17 dnawo
        ExifLookup.Add "GPSVersionID", "0000"
        ExifLookup.Add "GPSLatitudeRef", "0001"
        ExifLookup.Add "GPSLatitude", "0002"
        ExifLookup.Add "GPSLongitudeRef", "0003"
        ExifLookup.Add "GPSLongitude", "0004"
        ExifLookup.Add "GPSAltitudeRef", "0005"
        ExifLookup.Add "GPSAltitude", "0006"
        'Interoperability IFD Tags
        ExifLookup.Add "Interoperability Index", "01"
        ExifLookup.Add "Interoperability Version", "02"
        ExifLookup.Add "Related Image File Format", "1000"
        ExifLookup.Add "Related Image Width", "1001"
        ExifLookup.Add "Related Image Length", "1002"
        'IFD1 Tags
        ExifLookup.Add "Image Width", "0100"
        ExifLookup.Add "Image Height", "0101"
        ExifLookup.Add "Bits Per Sample", "0102"
        ExifLookup.Add "Compression", "0103"
        ExifLookup.Add "Photometric Interpretation", "0106"
        ExifLookup.Add "Strip Offsets", "0111"
        ExifLookup.Add "Sample Per Pixel", "0115"
        ExifLookup.Add "Rows Per Strip", "0116"
        ExifLookup.Add "Strip Byte Counts", "0117"
        ExifLookup.Add "X Resolution 2", "011A"
        ExifLookup.Add "Y Resolution 2", "011B"
        ExifLookup.Add "Planar Configuration", "011C"
        ExifLookup.Add "Resolution Unit 2", "0128"
        ExifLookup.Add "JPEG Interchange Format", "0201"
        ExifLookup.Add "JPEG Interchange Format Length", "0202"
        ExifLookup.Add "YCbCr Coeffecients", "0211"
        ExifLookup.Add "YCbCr Sub Sampling", "0212"
        ExifLookup.Add "YCbCr Positioning 2", "0213"
        ExifLookup.Add "Reference Black White 2", "0214"
        'Misc Tags
        ExifLookup.Add "New Subfile Type", "FE"
        ExifLookup.Add "Subfile Type", "FF"
        ExifLookup.Add "Transfer Function", "012D"
        ExifLookup.Add "Artist", "013B"
        ExifLookup.Add "Predictor", "013D"
        ExifLookup.Add "Tile Width", "0142"
        ExifLookup.Add "Tile Length", "0143"
        ExifLookup.Add "Tile Offsets", "0144"
        ExifLookup.Add "Tile Byte Counts", "0145"
        ExifLookup.Add "Sub IFDs", "014A"
        ExifLookup.Add "JPEG Tables", "015B"
        ExifLookup.Add "CFA Repeat Pattern Dim", "828D"
        ExifLookup.Add "CFA Pattern 2", "828E"
        ExifLookup.Add "Battery Level", "828F"
        ExifLookup.Add "IPTC_NAA", "83BB"
        ExifLookup.Add "Inter Color Profile", "8773"
        ExifLookup.Add "Spectral Sensitivity", "8824"
        ExifLookup.Add "GPS Info", "8825"
        ExifLookup.Add "OECF", "8828"
        ExifLookup.Add "Interlace", "8829"
        ExifLookup.Add "Time Zone Offset", "882A"
        ExifLookup.Add "Self Timer Mode", "882B"
        ExifLookup.Add "Flash Energy", "920B"
        ExifLookup.Add "Spatial Frequency Response", "920C"
        ExifLookup.Add "Noise", "920D"
        ExifLookup.Add "Image Number", "9211"
        ExifLookup.Add "Security Classification", "9212"
        ExifLookup.Add "Image History", "9213"
        ExifLookup.Add "Subject Location", "9214"
        ExifLookup.Add "Exposure Index 2", "9215"
        ExifLookup.Add "TIFFEP Standard ID", "9216"
        ExifLookup.Add "Flash Energy 2", "A20B"
        ExifLookup.Add "Spatial Frequency Response 2", "A20C"
        ExifLookup.Add "Subject Location 2", "A214"
        ExifTemp=array(0)
        IFDDirectory = array(0)
    End Sub
    
    Private Sub class_terminate()
    End Sub

    Public Property Let ImageFile(ByVal vNewValue)
        ImageFileName = vNewValue
        LoadImage ImageFileName
    End Property

    Public Property Get ImageFile()
        ImageFile=ImageFileName
    End Property

    Public Function LookupExifTag(which)
        dim item
        for each item in ExifLookup
            if ExifLookup(item) = which then
                LookupExifTag = item
                exit function
            end if
        next
        LookupExifTag = which
    End Function
    
    Public Function hasExifInfo()
        If IsLoaded = False or ImageFileName = "" Then
            hasExifInfo = False
        ElseIf UBound(IFDDirectory)<1 Then
            hasExifInfo = False
        Else
            hasExifInfo = True
        End If
    End Function
    
    Public Function GetExifByName(ExifTag)
        Dim i

        If IsLoaded = False And ImageFileName <> "" Then
            LoadImage (ImageFileName)
        ElseIf IsLoaded = False And ImageFileName = "" Then
            Exit Function
        End If
        For i = 0 To UBound(IFDDirectory) - 1
            If IFDDirectory(i)(IFD_IDX_Tag_Name) = ExifTag Then
                If IFDDirectory(i)(IFD_IDX_Value_Desc) <> "" then
                    GetExifByName = IFDDirectory(i)(IFD_IDX_Value_Desc)
                Else
                    GetExifByName = IFDDirectory(i)(IFD_IDX_Value)
                End if
                Exit For
            End If
        Next
    End Function
    
    Private sub LoadImage(picFile)
        If ImageFileName = "" Then
            ImageFileName = picFile
            If ImageFileName = "" Then
                Exit sub
            End If
        End If
        OpenJPGFile ImageFileName
        If InspectJPGFile = False Then
            IsLoaded = False
            Exit Sub
        End If
        If IsIntel Then
            Offset_to_IFD0 = ByteToLong(ExifTemp(Offset_to_APP1 + 17), ExifTemp(Offset_to_APP1 + 16), ExifTemp(Offset_to_APP1 + 15), ExifTemp(Offset_to_APP1 + 14))
        Else
            Offset_to_IFD0 = ByteToLong(ExifTemp(Offset_to_APP1 + 14), ExifTemp(Offset_to_APP1 + 15), ExifTemp(Offset_to_APP1 + 16), ExifTemp(Offset_to_APP1 + 17))
        End If
        IsLoaded = True
        GetDirectoryEntries Offset_to_TIFF + Offset_to_IFD0
        MakeSenseOfMeaninglessValues
    End sub
    
    Private Function InspectJPGFile()
        Dim i

        if UBound(ExifTemp)<=0 then
            InspectJPGFile = False
            Exit Function
        end if
        If ExifTemp(0) <> &HFF And ExifTemp(1) <> &HD8 Then
            InspectJPGFile = False
        Else
            For i = 2 To UBound(ExifTemp) - 1
                If ExifTemp(i) = &HFF And ExifTemp(i + 1) = &HE1 Then
                    Offset_to_APP1 = i
                    Exit For
                End If
            Next
            If Offset_to_APP1 = 0 Then
                InspectJPGFile = False
            End If
            Offset_to_TIFF = Offset_to_APP1 + 10
            Length_of_APP1 = ByteToInt(ExifTemp(Offset_to_APP1 + 2), ExifTemp(Offset_to_APP1 + 3))
            If Not (ExifTemp(Offset_to_APP1 + 4) = ASC("E") And ExifTemp(Offset_to_APP1 + 5) = ASC("x") And ExifTemp(Offset_to_APP1 + 6) = ASC("i") And ExifTemp(Offset_to_APP1 + 7) = ASC("f")) Then
                InspectJPGFile = False
                Exit Function
            End If
            InspectJPGFile = True
        End If
    End Function
    
    Private Function IsIntel()
        If ExifTemp(Offset_to_TIFF) = &H49 Then
            IsIntel = True
        Else
            IsIntel = False
        End If
    End Function
    
    Private Function OpenJPGFile(FileName)
        const TristateUseDefault = -2
        const TristateTrue = -1
        const TristateFalse = 0
        const ForReading = 1
        const ForWriting = 2
        const ForAppending = 8

        Dim Ascii, LastByte, CurByte, SOSFound
        Dim FSO, File, i
    
        If Not FileName = "" Then
            If InStr(1, FileName, ":\") = 0 Then
                FileName = Server.MapPath(FileName)
            End If
            Set FSO = Server.CreateObject("Scripting.FileSystemObject")
            If FSO.FileExists(FileName) Then
                Set File = Server.CreateObject("ADODB.Stream")
                File.Type = 1
                File.Mode = 3
                File.Open
                File.LoadFromFile FileName
                i = 0
                While Not File.EOS and SOSFound = false
                    Ascii = ascb(File.Read(1))
                    LastByte = CurByte
                    CurByte = Ascii
                    '读到SOS Maker
                    If (LastByte = &HFF and CurByte = &HDA) or i > 100000 Then
                        SOSFound = true
                    End If
                    ExifTemp(i) = CurByte
                    i = i + 1
                    ReDim Preserve ExifTemp(i)
                Wend
                File.Close
                Set File = Nothing
            End If
            Set FSO = Nothing
        End If
    End Function
    
    Private Sub GetDirectoryEntries(Offset)
        const ExifOffset = "8769"
        const GPSOffset = "8825"
        const MakerNote = "927C"
        
        const m_BYTE = 1
        const m_STRING = 2
        const m_SHORT = 3
        const m_LONG = 4
        const m_RATIONAL = 5
        const m_SBYTE = 6
        const m_UNDEFINED = 7
        const m_SSHORT = 8
        const m_SLONG = 9
        const m_SRATIONAL = 10
        const m_SINGLE = 11
        const m_DOUBLE = 12
        
        Dim No_of_Entries
        Dim Upper_IFDDirectory
        Dim NewDimensions
        Dim Processed_ExifSubIFD
        Dim BytesPerComponent
        Dim Offset_to_MakerNote
        Dim i, j, k
    
        If IsIntel Then
            No_of_Entries = ByteToInt(ExifTemp(Offset + 1), ExifTemp(Offset + 0))
        Else
            No_of_Entries = ByteToInt(ExifTemp(Offset + 0), ExifTemp(Offset + 1))
        End If
        On Error Resume Next
        Upper_IFDDirectory = UBound(IFDDirectory)
        On Error GoTo 0
        NewDimensions = Upper_IFDDirectory + No_of_Entries
        ReDim Preserve IFDDirectory(NewDimensions)
        For i = 1 To No_of_Entries
            k = Upper_IFDDirectory + i - 1
            IFDDirectory(k) = array(null,null,null,null,null,null,null)
            If IsIntel Then
                IFDDirectory(k)(IFD_IDX_Tag_No) = Hex0(ExifTemp((Offset + 2) + ((i - 1) * 12) + 1)) & Hex0(ExifTemp((Offset + 2) + ((i - 1) * 12) + 0))
                IFDDirectory(k)(IFD_IDX_Data_Format) = ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 3), ExifTemp((Offset + 2) + ((i - 1) * 12) + 2))
                IFDDirectory(k)(IFD_IDX_Components) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 7), ExifTemp((Offset + 2) + ((i - 1) * 12) + 6), ExifTemp((Offset + 2) + ((i - 1) * 12) + 5), ExifTemp((Offset + 2) + ((i - 1) * 12) + 4))
                Select Case IFDDirectory(k)(IFD_IDX_Data_Format)
                Case m_BYTE, m_SBYTE
                    BytesPerComponent = 1
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                        IFDDirectory(k)(IFD_IDX_Value) = ByteToByte((Offset + 2) + ((i - 1) * 12) + 8, (Offset + 2) + ((i - 1) * 12) + 8 + IFDDirectory(k)(IFD_IDX_Components) - 1)
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 11), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToByte(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue), Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1)
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = "00"
                        End if
                    End If
                Case m_STRING, m_UNDEFINED
                    BytesPerComponent = 1
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                        IFDDirectory(k)(IFD_IDX_Value) = ByteToStr((Offset + 2) + ((i - 1) * 12) + 8, (Offset + 2) + ((i - 1) * 12) + 8 + IFDDirectory(k)(IFD_IDX_Components) - 1)
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 11), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToStr(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue), Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1)
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = ""
                        End if
                    End If
                Case m_SHORT, m_SSHORT
                    BytesPerComponent = 2
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        Select Case IFDDirectory(k)(IFD_IDX_Components)
                        Case 1
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                        Case 2
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 11), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10)) + ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                        End Select
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 11), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToByte(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue), Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1)
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = 0
                        End if
                    End If
                Case m_LONG, m_SLONG
                    BytesPerComponent = 4
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        IFDDirectory(k)(IFD_IDX_Value) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 11), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 11), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToByte(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue), Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1)
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = 0
                        End if
                    End If
                Case m_RATIONAL, m_SRATIONAL
                    BytesPerComponent = 8
                    IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 11), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 8))
                    Select Case IFDDirectory(k)(IFD_IDX_Components)
                        Case 1
                            If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                                IFDDirectory(k)(IFD_IDX_Value) = ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 3), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 2), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 1), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 0)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 7), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 6), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 5), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 4))
                            Else
                                IFDDirectory(k)(IFD_IDX_Value) = "0/0"
                            End If
                        Case 3 'GPS
                            If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                                IFDDirectory(k)(IFD_IDX_Value) = ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 3), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 2), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 1), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 0)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 7), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 6), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 5), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 4)) & "," & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 11), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 10), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 9), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 8)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 15), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 14), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 13), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 12)) & "," & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 19), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 18), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 17), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 16)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 23), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 22), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 21), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 20))
                            Else
                                IFDDirectory(k)(IFD_IDX_Value) = "0/0,0/0,0/0"
                            End If
                    End Select
                End Select
            Else
                IFDDirectory(k)(IFD_IDX_Tag_No) = Hex0(ExifTemp((Offset + 2) + ((i - 1) * 12) + 0)) & Hex0(ExifTemp((Offset + 2) + ((i - 1) * 12) + 1))
                IFDDirectory(k)(IFD_IDX_Data_Format) = ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 2), ExifTemp((Offset + 2) + ((i - 1) * 12) + 3))
                IFDDirectory(k)(IFD_IDX_Components) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 4), ExifTemp((Offset + 2) + ((i - 1) * 12) + 5), ExifTemp((Offset + 2) + ((i - 1) * 12) + 6), ExifTemp((Offset + 2) + ((i - 1) * 12) + 7))
                Select Case IFDDirectory(k)(IFD_IDX_Data_Format)
                Case m_BYTE, m_SBYTE
                    BytesPerComponent = 1
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                        IFDDirectory(k)(IFD_IDX_Value) = ByteToByte((Offset + 2) + ((i - 1) * 12) + 8, (Offset + 2) + ((i - 1) * 12) + 8 + IFDDirectory(k)(IFD_IDX_Components) - 1)
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 11))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToByte(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue), Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1)
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = "00"
                        End If
                    End If
                Case m_STRING, m_UNDEFINED
                    BytesPerComponent = 1
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                        IFDDirectory(k)(IFD_IDX_Value) = ByteToStr((Offset + 2) + ((i - 1) * 12) + 8, (Offset + 2) + ((i - 1) * 12) + 8 + IFDDirectory(k)(IFD_IDX_Components) - 1)
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 11))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToStr(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue), Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1)
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = ""
                        End If
                    End If
                Case m_SHORT, m_SSHORT
                    BytesPerComponent = 2
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        Select Case IFDDirectory(k)(IFD_IDX_Components)
                        Case 1
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9))
                        Case 2
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9)) + ByteToInt(ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 11))
                        End Select
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 11))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToByte(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1, Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue))
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = 0
                        End If
                    End If
                Case m_LONG, m_SLONG
                    BytesPerComponent = 4
                    If IFDDirectory(k)(IFD_IDX_Components) * BytesPerComponent <= 4 Then
                        IFDDirectory(k)(IFD_IDX_Value) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 11))
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = 0
                    Else
                        IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 11))
                        If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                            IFDDirectory(k)(IFD_IDX_Value) = ByteToByte(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + IFDDirectory(k)(IFD_IDX_Components) - 1, Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue))
                        Else
                            IFDDirectory(k)(IFD_IDX_Value) = 0
                        End If
                    End If
                Case m_RATIONAL, m_SRATIONAL
                    BytesPerComponent = 8
                    IFDDirectory(k)(IFD_IDX_OffsetToValue) = ByteToLong(ExifTemp((Offset + 2) + ((i - 1) * 12) + 8), ExifTemp((Offset + 2) + ((i - 1) * 12) + 9), ExifTemp((Offset + 2) + ((i - 1) * 12) + 10), ExifTemp((Offset + 2) + ((i - 1) * 12) + 11))
                    Select Case IFDDirectory(k)(IFD_IDX_Components)
                        Case 1
                            If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                                IFDDirectory(k)(IFD_IDX_Value) = ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 0), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 1), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 2), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 3)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 4), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 5), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 6), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 7))
                            Else
                                IFDDirectory(k)(IFD_IDX_Value) = "0/0"
                            End If
                        Case 3 'GPS
                            If Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) < UBound(ExifTemp) Then
                                IFDDirectory(k)(IFD_IDX_Value) = ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 0), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 1), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 2), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 3)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 4), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 5), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 6), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 7)) & "," & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 8), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 9), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 10), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 11)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 12), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 13), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 14), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 15)) & "," & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 16), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 17), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 18), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 19)) & "/" & ByteToLong(ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 20), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 21), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 22), ExifTemp(Offset_to_TIFF + IFDDirectory(k)(IFD_IDX_OffsetToValue) + 23))
                            Else
                                IFDDirectory(k)(IFD_IDX_Value) = "0/0,0/0,0/0"
                            End If
                    End Select
                End Select
            End If
            If IFDDirectory(k)(IFD_IDX_Tag_No) = MakerNote Then
                Offset_to_MakerNote = IFDDirectory(k)(IFD_IDX_OffsetToValue)
            End If
            'ExifIFD,GPSIFD解析
            If IFDDirectory(k)(IFD_IDX_Tag_No) = ExifOffset or IFDDirectory(k)(IFD_IDX_Tag_No) = GPSOffset Then
                Offset_to_ExifSubIFD = CLng(IFDDirectory(k)(IFD_IDX_Value))
                GetDirectoryEntries Offset_to_TIFF + Offset_to_ExifSubIFD
            End If
            IFDDirectory(k)(IFD_IDX_Tag_Name) = LookupExifTag(IFDDirectory(k)(IFD_IDX_Tag_No))
        Next
    End Sub
    
    Private Function Hex0(nValue)
        Hex0 = Right("00" & Hex(nValue), 2)
    End Function
    
    Private Function ByteToInt(Byte1, Byte2)
        If Byte1 < 128 Then
            ByteToInt = Byte1 * 256 + Byte2
        Else
            ByteToInt = Byte2 - (256 - Byte1) * 256
        End If
    End Function
    
    Private Function ByteToLong(Byte1, Byte2, Byte3, Byte4)
        If Byte1 < 128 Then
            ByteToLong = ((Byte1 * 256 + Byte2) * 256 + Byte3) * 256 + Byte4
        Else
            ByteToLong = Byte4 - (((256 - Byte1) * 256 - Byte2) * 256 - Byte3) * 256
        End If
    End Function

    Private Function ByteToStr(StartOffset, EndOffset)
        Dim i
        
        ByteToStr = ""
        If StartOffset > EndOffset Then
            For i = StartOffset To EndOffset Step -1
                If ExifTemp(i) = 0 Then Exit For
                If i > EndOffset Then
                    If ExifTemp(i) >= 128 and ExifTemp(i - 1) >= 128 Then
                        ByteToStr = ByteToStr & Chr(ByteToInt(ExifTemp(i), ExifTemp(StartOffset + i - 1)))
                        i = i - 1
                    Else
                        ByteToStr = ByteToStr & Chr(ExifTemp(i))
                    End If
                Else
                    ByteToStr = ByteToStr & Chr(ExifTemp(i))
                End If
            Next
        Else
            For i = StartOffset To EndOffset
                If ExifTemp(i) = 0 Then Exit For
                If i < EndOffset Then
                    If ExifTemp(i) >= 128 and ExifTemp(i + 1) >= 128 Then
                        ByteToStr = ByteToStr & Chr(ByteToInt(ExifTemp(i), ExifTemp(i + 1)))
                        i = i + 1
                    Else
                        ByteToStr = ByteToStr & Chr(ExifTemp(i))
                    End If
                Else
                    ByteToStr = ByteToStr & Chr(ExifTemp(i))
                End If
            Next
        End If
    End Function
    
    Private Function ByteToByte(StartOffset, EndOffset)
        Dim i
        
        ByteToByte = ""
        If StartOffset > EndOffset Then
            For i = StartOffset To EndOffset Step -1
                If ByteToByte <> "" Then ByteToByte = ByteToByte & " "
                ByteToByte = ByteToByte & Hex0(ExifTemp(i))
            Next
        Else
            For i = StartOffset To EndOffset
                If ByteToByte <> "" Then ByteToByte = ByteToByte & " "
                ByteToByte = ByteToByte & Hex0(ExifTemp(i))
            Next
        End If
    End Function

    Private Function MakeSenseOfMeaninglessValues()
        Dim x
        Dim TagValues
        
        For x = 0 To ubound(IFDDirectory) - 1
            Select Case IFDDirectory(x)(IFD_IDX_Tag_Name)
            Case "Orientation"
                TagValues = array("未知","上左","上右", "下右", "下左", "左上", "右上", "右下", "左下")
                If IFDDirectory(x)(IFD_IDX_Value)>=0 and IFDDirectory(x)(IFD_IDX_Value)<ubound(TagValues) Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = TagValues(IFDDirectory(x)(IFD_IDX_Value))
                Else
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = "未知"
                End if
            Case "Metering Mode"
                TagValues = array("未知","平均","偏中心平均", "点", "多点", "图案", "部分")
                If IFDDirectory(x)(IFD_IDX_Value)>=0 and IFDDirectory(x)(IFD_IDX_Value)<ubound(TagValues) Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = TagValues(IFDDirectory(x)(IFD_IDX_Value))
                Else
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = "未知"
                End if
            Case "FStop"
                TagValues = Split(IFDDirectory(x)(IFD_IDX_Value), "/")
                If UBound(TagValues) = 1 Then
                    If CLng(TagValues(1))<>0 Then
                        If (CLng(TagValues(0)) Mod CLng(TagValues(1))) = 0 Then
                            IFDDirectory(x)(IFD_IDX_Value_Desc) = "F/" & (CLng(TagValues(0)) \ CLng(TagValues(1)))
                        Else
                            IFDDirectory(x)(IFD_IDX_Value_Desc) = "F/" & Round(CLng(TagValues(0)) / CLng(TagValues(1)),1)
                        End If
                    End If
                End if
            Case "Exposure Time"
                TagValues = Split(IFDDirectory(x)(IFD_IDX_Value), "/")
                If UBound(TagValues) = 1 Then
                    If CLng(TagValues(1))<>0 Then
                        If CLng(TagValues(1)) > CLng(TagValues(0)) Then
                            If (CLng(TagValues(1)) Mod CLng(TagValues(0))) = 0 Then
                                IFDDirectory(x)(IFD_IDX_Value_Desc) = "1/" & (CLng(TagValues(1)) \ CLng(TagValues(0))) & " 秒"
                            Else
                                IFDDirectory(x)(IFD_IDX_Value_Desc) = "1/" & Round(CLng(TagValues(1)) / CLng(TagValues(0)),1) & " 秒"
                            End If
                        Else
                            If (CLng(TagValues(0)) Mod CLng(TagValues(1))) = 0 Then
                                IFDDirectory(x)(IFD_IDX_Value_Desc) = CLng(TagValues(0)) \ CLng(TagValues(1)) & " 秒"
                            Else
                                IFDDirectory(x)(IFD_IDX_Value_Desc) = Round(CLng(TagValues(0)) / CLng(TagValues(1)),1) & " 秒"
                            End If
                        End if
                    End if
                End if
            Case "Flash"
                If (IFDDirectory(x)(IFD_IDX_Value) Mod 2) = 0 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = "关"
                Else
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = "开"
                End If
                TagValues = IFDDirectory(x)(IFD_IDX_Value) \ 2
                If (TagValues Mod 4) = 2 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "[无选通返回]"
                ElseIf (TagValues Mod 4) = 3 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "[带选通返回]"
                End If
                TagValues = TagValues \ 4
                If (TagValues Mod 4) = 1 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "[强制闪光]"
                ElseIf (TagValues Mod 4) = 2 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "[强制关闭]"
                ElseIf (TagValues Mod 4) = 3 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "[自动闪光]"
                End If
                TagValues = TagValues \ 4
                If (TagValues Mod 2) = 1 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "[无闪光灯]"
                End If
                TagValues = TagValues \ 2
                If (TagValues Mod 2) = 1 Then
                    IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "[去红眼]"
                End If
            Case "Exposure Bias Value"
                TagValues = Split(IFDDirectory(x)(IFD_IDX_Value),"/")
                If UBound(TagValues) = 1 Then
                    If CLng(TagValues(1))<>0 Then
                        If CLng(TagValues(0)) > 0 Then
                            IFDDirectory(x)(IFD_IDX_Value_Desc) = "+ "
                        ElseIf CLng(TagValues(0)) = 0 then
                            IFDDirectory(x)(IFD_IDX_Value_Desc) = "0"
                        Else
                            IFDDirectory(x)(IFD_IDX_Value_Desc) = "- "
                        End If
                        If TagValues(0)<>0 Then
                            If CLng(Abs(TagValues(0))) < CLng(Abs(TagValues(1))) And CLng(TagValues(0)) <> 0 Then IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "0"
                            IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & Round(CLng(Abs(TagValues(0))) / CLng(Abs(TagValues(1))),1)
                        End If
                        IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & "EV"
                    End If
                End if
            Case "Focal Length"
                TagValues = Split(IFDDirectory(x)(IFD_IDX_Value),"/")
                If UBound(TagValues) = 1 Then
                    If CLng(TagValues(1))<>0 Then
                        IFDDirectory(x)(IFD_IDX_Value_Desc) = Round(CLng(TagValues(0)) / CLng(TagValues(1)),1)
                    End If
                End If
                IFDDirectory(x)(IFD_IDX_Value_Desc) = IFDDirectory(x)(IFD_IDX_Value_Desc) & " 毫米"
            End Select
        Next
    End Function
    
    Public Function ExifAllInfo()
        ExifAllInfo="<table border=1><tr><th nowrap>#</td><th nowrap>Tag HEX</td><th nowrap>Tag Name</td><th nowrap>Format</td><th nowrap>Size</td><th nowrap>Offset</td><th nowrap>Value</td><th nowrap>Value Described</td></tr>"
        dim x
        for x = 0 to ubound(IFDDirectory) - 1
            ExifAllInfo=ExifAllInfo& "<tr>"
            ExifAllInfo=ExifAllInfo& "<td>" & x & "</td>"
            ExifAllInfo=ExifAllInfo& "<td>" & IFDDirectory(x)(IFD_IDX_Tag_No) & "</td>"
            ExifAllInfo=ExifAllInfo& "<td>" & IFDDirectory(x)(IFD_IDX_Tag_Name) & "</td>"
            ExifAllInfo=ExifAllInfo& "<td>" & IFDDirectory(x)(IFD_IDX_Data_Format) & "</td>"
            ExifAllInfo=ExifAllInfo& "<td>" & IFDDirectory(x)(IFD_IDX_Components) & "</td>"
            ExifAllInfo=ExifAllInfo& "<td>" & IFDDirectory(x)(IFD_IDX_OffsetToValue) & "</td>"
            ExifAllInfo=ExifAllInfo& "<td>" & IFDDirectory(x)(IFD_IDX_Value) & "</td>"
            ExifAllInfo=ExifAllInfo& "<td>" & IFDDirectory(x)(IFD_IDX_Value_Desc) & "</td></tr>"
        next
        ExifAllInfo=ExifAllInfo& "</table>"
    End Function

    Public Function ExifAllInfo2()
        ExifAllInfo2="<BR>"
        dim x
        for x = 0 to ubound(ExifTemp)
            ExifAllInfo2=ExifAllInfo2& ExifTemp(x)&" "
        next
    End Function
End Class
%>

调用示例:

<!--#include file="Exif.asp" -->
<%
Set Obj = new Cls_Exif
Obj.ImageFile = Server.MapPath("pic/test.jpg")
Response.Write(Obj.GetExifByName("GPSLatitude"))
Response.Write(Obj.ExifAllInfo())
%>

本类源代码从网上下载而来[下载原文件],原先只能获取IFD0、ExifIFD和两块信息,经修改后增加了GSIFD信息读取。

评论: 0 | 引用: 0 | 查看次数: 9362
发表评论
登录后再发表评论!