Author Topic: Extracting GPS information from a JPG file  (Read 750 times)

TheStingPilot

  • Newbie
  • *
  • Posts: 6
Extracting GPS information from a JPG file
« on: July 11, 2020, 10:27:24 AM »
Hello,

I am writing a PowerShell function that reads the EXIF information from a JPG file.
Code: [Select]
Function Get-EXIFDataFromJPGFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       06-July-2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-EXIFDataFromJPGFile
    =============================================================================================================================================
    .SYNOPSIS

    This function reads the latitude and longitude data from a JPG file.
    If no valid data is found, the return codes will be 1024 and 1024.
    This code is based on
    http://www.forensicexpedition.com/2017/08/03/imagemapper-a-powershell-metadata-and-geo-maping-tool-for-images/

    #>

    Param
     (
      [String] $FileName
     )
   
   
    $img    = New-Object -TypeName system.drawing.bitmap -ArgumentList $FileName
    $Encode = New-Object System.Text.ASCIIEncoding
    $GPSInfo = $true
    $GPSLat  = ""
    $GPSLon  = ""
     
    # =============================================================================================================================================
    # Try to get the latitude (N or S) from the image.
    # If not successfull then this information is not in the image
    # and quit with the numbers 1024 and 1024.
    # =============================================================================================================================================

    Try
     {
     
      $LatNS = $Encode.GetString($img.GetPropertyItem(1).Value)
     }
      Catch
     {
      $GPSInfo = $False
     }
               
    If ($GPSInfo -eq $true)
     {
      [double]$LatDeg = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 0))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 4)))
      [double]$LatMin = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 8))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 12)))
      [double]$LatSec = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 16)) / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 20)))
   
      $LonEW = $Encode.GetString($img.GetPropertyItem(3).Value)
      [double]$LonDeg = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 0))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 4)))
      [double]$LonMin = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 8))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 12)))
      [double]$LonSec = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 16)) / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 20)))



      #$GPSLat = $($LatDeg.ToString("###")) + "º "+$($LatMin.ToString("##"))+"' "+$($LatSec.ToString("##"))+ $([char]34) + " "+$LatNS
      #$GPSLon = $($LonDeg.ToString("###")) + "º "+$($LonMin.ToString("##"))+"' "+$($LonSec.ToString("##"))+ $([char]34) + " "+$LonEW

      $GPSLat = "$([int]$LatDeg)º $([int]$LatMin)' $([int]$LatSec)$([char]34) $LatNS"
      $GPSLon = "$([int]$LonDeg)º $([int]$LonMin)' $([int]$LonSec)$([char]34) $LonEW"

      Write-Verbose "    The picture $FileName has the following GPS coordinates:"
      Write-Verbose "       $GPSLat"       
      Write-Verbose "       $GPSLon"

    # =============================================================================================================================================
    # Convert the latitude and longitude to numbers that Google Maps recognizes.
    # =============================================================================================================================================

      $LatOrt = 0
      $LonOrt = 0

      If ($LatNS -eq 'S')
       {
        $LatOrt = "-"   
       }
      If ($LonEW -eq 'W')
       {
        $LonOrt = "-"
       }

      $LatDec = ($LatDeg + ($LatMin/60) + ($LatSec/3600))
      $LonDec = ($LonDeg + ($LonMin/60) + ($LonSec/3600))

      $LatOrt = $LatOrt + $LatDec
      $LonOrt = $LonOrt + $LonDec

    # =============================================================================================================================================
    # The numbers that where returned contained a decimal comma instead of a decimal point.
    # So the en-US culture is forced to get the correct number notation.
    # =============================================================================================================================================
   
      $LatOrt = $LatOrt.ToString([cultureinfo]::GetCultureInfo('en-US'))
      $LonOrt = $LonOrt.ToString([cultureinfo]::GetCultureInfo('en-US'))

      Write-Verbose "    The picture $FileName has the following decimal coordinates:"
      Write-Verbose "      $LatOrt"
      Write-Verbose "      $LonOrt"
    }
     else
    {
     
   # =============================================================================================================================================
   # Ohoh... No GPS information in this picture.
   # =============================================================================================================================================
     
     Write-Verbose "    The picture $FileName does not contain GPS information."
     $LatOrt = "1024"
     $LonOrt = "1024"
    }

    Return $LatOrt,$LonOrt,$GPSLat,$GPSLon
  }

  Add-Type -AssemblyName System.Drawing
  Get-EXIFDataFromJPGFile "C:\TMP\WP_20170426_15_30_51_Pro.jpg"

There are two things I do not understand.
  • In some cases the minutes and seconds are negative. That happens with Nolia Lumia 930 camera's
  • My script does not find any GPS information and your tool does.

So my simple question is: what should I do to get the correct information from the JPG files. :-)

Your feedback is appreciated and with kind regards,
TheStingPilot

StarGeek

  • Global Moderator
  • ExifTool Freak
  • *****
  • Posts: 4064
Re: Extracting GPS information from a JPG file
« Reply #1 on: July 11, 2020, 10:51:29 AM »
My script does not find any GPS information and your tool does.

What is the location of the GPS data?  Group name, not actual location.  Use the command in FAQ #3 to see the actual group the tags belong to.

GPS coordinates can also be in the XMP data, though it usually isn't exclusively there.
Troubleshooting hints:
* When posting, include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).
* Double all percent signs (%) in a Windows batch file.
* If your GPS coords are negative, make sure and set the GpsLatitudeRef and GpsLongitudeRef tags correctly.

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 17018
    • ExifTool Home Page
Re: Extracting GPS information from a JPG file
« Reply #2 on: July 11, 2020, 10:55:42 AM »
I don't know what GetPropertyItem() does, so I can't help much.

But I do know that PowerShell easily mangles binary data, converting newlines to CR/LF sequences.  So watch out for that.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

TheStingPilot

  • Newbie
  • *
  • Posts: 6
Re: Extracting GPS information from a JPG file
« Reply #3 on: July 12, 2020, 04:12:49 AM »
My script does not find any GPS information and your tool does.

What is the location of the GPS data?  Group name, not actual location.  Use the command in FAQ #3 to see the actual group the tags belong to.

GPS coordinates can also be in the XMP data, though it usually isn't exclusively there.

Helllo StarGeek,

Thanks for your response.

The (requested) output:
Code: [Select]
[ExifTool]      ExifToolVersion                 : 12.01
[ExifTool]      Warning                         : [minor] Unrecognized MakerNotes
[ExifTool]      Warning                         : [minor] Fixed incorrect URI for xmlns:MicrosoftPhoto
[System]        FileName                        : WP_20170426_15_30_51_Pro.jpg
[System]        Directory                       : C:/tmp
[System]        FileSize                        : 4.9 MB
[System]        FileModifyDate                  : 2017:04:26 15:30:54+02:00
[System]        FileAccessDate                  : 2020:07:12 09:59:36+02:00
[System]        FileCreateDate                  : 2020:07:12 09:55:08+02:00
[System]        FilePermissions                 : rw-rw-rw-
[File]          FileType                        : JPEG
[File]          FileTypeExtension               : jpg
[File]          MIMEType                        : image/jpeg
[File]          ExifByteOrder                   : Big-endian (Motorola, MM)
[File]          ImageWidth                      : 5376
[File]          ImageHeight                     : 3024
[File]          EncodingProcess                 : Baseline DCT, Huffman coding
[File]          BitsPerSample                   : 8
[File]          ColorComponents                 : 3
[File]          YCbCrSubSampling                : YCbCr4:2:0 (2 2)
[IFD0]          Make                            : Microsoft
[IFD0]          Model                           : Lumia 930
[IFD0]          Orientation                     : Horizontal (normal)
[IFD0]          XResolution                     : 72
[IFD0]          YResolution                     : 72
[IFD0]          ResolutionUnit                  : inches
[IFD0]          Software                        : Windows Phone
[IFD0]          YCbCrPositioning                : Centered
[IFD0]          Padding                         : (Binary data 2060 bytes, use -b option to extract)
[ExifIFD]       ExposureTime                    : 1/1330
[ExifIFD]       FNumber                         : 2.4
[ExifIFD]       ISO                             : 64
[ExifIFD]       ExifVersion                     : 0220
[ExifIFD]       DateTimeOriginal                : 2017:04:26 15:30:52
[ExifIFD]       CreateDate                      : 2017:04:26 15:30:52
[ExifIFD]       ComponentsConfiguration         : Y, Cb, Cr, -
[ExifIFD]       ShutterSpeedValue               : 1/1330
[ExifIFD]       ApertureValue                   : 2.4
[ExifIFD]       ExposureCompensation            : 0
[ExifIFD]       MeteringMode                    : Average
[ExifIFD]       LightSource                     : Unknown
[ExifIFD]       Flash                           : Auto, Fired
[ExifIFD]       FocalLength                     : 4.5 mm
[ExifIFD]       SubSecTimeOriginal              : 797
[ExifIFD]       SubSecTimeDigitized             : 797
[ExifIFD]       FlashpixVersion                 : 0100
[ExifIFD]       ColorSpace                      : sRGB
[ExifIFD]       ExifImageWidth                  : 5376
[ExifIFD]       ExifImageHeight                 : 3024
[ExifIFD]       ExposureMode                    : Auto
[ExifIFD]       WhiteBalance                    : Auto
[ExifIFD]       DigitalZoomRatio                : 0
[ExifIFD]       FocalLengthIn35mmFormat         : 28 mm
[ExifIFD]       SceneCaptureType                : Standard
[ExifIFD]       Padding                         : (Binary data 2048 bytes, use -b option to extract)
[ExifIFD]       OffsetSchema                    : 0
[GPS]           GPSLatitudeRef                  : North
[GPS]           GPSLatitude                     : 47 deg 33' 21.95"
[GPS]           GPSLongitudeRef                 : East
[GPS]           GPSLongitude                    : 7 deg 35' 30.37"
[XMP-microsoft] CreatorAppID                    : {2d7e7fd6-2942-4d77-9842-389c3f62b14d}
[XMP-microsoft] CreatorOpenWithUIOptions        : 1
[XMP-mwg-rs]    RegionAppliedToDimensionsH      : 3024
[XMP-mwg-rs]    RegionAppliedToDimensionsUnit   : pixel
[XMP-mwg-rs]    RegionAppliedToDimensionsW      : 5376
[XMP-mwg-rs]    RegionTitle                     : LumiaOriginalROI
[XMP-mwg-rs]    RegionAreaX                     : 0.500000
[XMP-mwg-rs]    RegionAreaY                     : 0.500000
[XMP-mwg-rs]    RegionAreaW                     : 1.000000
[XMP-mwg-rs]    RegionAreaH                     : 1.000000
[XMP-mwg-rs]    RegionAreaUnit                  : normalized
[XMP-Nokia]     SharpeningStrength              : 33554710
[Composite]     Aperture                        : 2.4
[Composite]     ImageSize                       : 5376x3024
[Composite]     Megapixels                      : 16.3
[Composite]     ScaleFactor35efl                : 6.3
[Composite]     ShutterSpeed                    : 1/1330
[Composite]     SubSecCreateDate                : 2017:04:26 15:30:52.797
[Composite]     SubSecDateTimeOriginal          : 2017:04:26 15:30:52.797
[Composite]     GPSLatitude                     : 47 deg 33' 21.95" N
[Composite]     GPSLongitude                    : 7 deg 35' 30.37" E
[Composite]     CircleOfConfusion               : 0.005 mm
[Composite]     FOV                             : 65.5 deg
[Composite]     FocalLength35efl                : 4.5 mm (35 mm equivalent: 28.0 mm)
[Composite]     GPSPosition                     : 47 deg 33' 21.95" N, 7 deg 35' 30.37" E
[Composite]     HyperfocalDistance              : 1.73 m
[Composite]     LightValue                      : 13.5

If I check that with my scripts output (same picture):

Code: [Select]
47º 33' -21" N
7º 35' -13" E

So there is a mismatch.  :(

The (correct) information is there (it is in the EXIFtool's output). The question is: how do I extract it from the image with PowerShell?  :)

With kind regards,
TheStingPilot

TheStingPilot

  • Newbie
  • *
  • Posts: 6
Re: Extracting GPS information from a JPG file
« Reply #4 on: July 12, 2020, 04:21:47 AM »
I don't know what GetPropertyItem() does, so I can't help much. (...)
- Phil

Hello Phil,

Thanks for your response. GetPropertyItem() reads the Exif information from a JPG file and processes it. It reads the EXIF information as per https://exiftool.org/TagNames/GPS.html.

Code: [Select]
$LatNS = $Encode.GetString($img.GetPropertyItem(1).Value)
[double]$LatDeg = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 0))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 4)))
[double]$LatMin = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 8))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 12)))
[double]$LatSec = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 16)) / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(2).Value, 20)))
   
$LonEW = $Encode.GetString($img.GetPropertyItem(3).Value)
[double]$LonDeg = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 0))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 4)))
[double]$LonMin = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 8))  / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 12)))
[double]$LonSec = (([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 16)) / ([Decimal][System.BitConverter]::ToInt32($img.GetPropertyItem(4).Value, 20)))


I am not afraid of mangled binary data as the output from many other picture files seems to be right.

With kind regards,
TheStingPilot

Phil Harvey

  • ExifTool Author
  • Administrator
  • ExifTool Freak
  • *****
  • Posts: 17018
    • ExifTool Home Page
Re: Extracting GPS information from a JPG file
« Reply #5 on: July 12, 2020, 07:20:52 AM »
Is ToInt32() a signed or unsigned integer?  The values should be stored as unsigned, so there should be no way to get a negative number if they are decoded as such.

- Phil
...where DIR is the name of a directory/folder containing the images.  On Mac/Linux, use single quotes (') instead of double quotes (") around arguments containing a dollar sign ($).

TheStingPilot

  • Newbie
  • *
  • Posts: 6
Re: Extracting GPS information from a JPG file
« Reply #6 on: July 12, 2020, 07:34:32 AM »
Hellp Phil,

Thanks for getting back to me. I assume it is signed... See https://docs.microsoft.com/en-us/dotnet/api/system.convert.toint32?view=netcore-3.1. Although I am not using .net.

Does the EXIF tool also use this information https://exiftool.org/TagNames/GPS.html to read jpg files? If so, why does the information not match even the same information source is used?

With kind regards,
TheStingPilot

StarGeek

  • Global Moderator
  • ExifTool Freak
  • *****
  • Posts: 4064
Re: Extracting GPS information from a JPG file
« Reply #7 on: July 12, 2020, 12:11:34 PM »
Thanks for getting back to me. I assume it is signed... See https://docs.microsoft.com/en-us/dotnet/api/system.convert.toint32?view=netcore-3.1. Although I am not using .net.

Try Convert.ToUInt32 Method.  As Phil mentioned, the data is unsigned.  The ToInt32 specifically says signed on the page you linked.

Quote
Does the EXIF tool also use this information https://exiftool.org/TagNames/GPS.html to read jpg files?

That's the list of GPS tags that exiftool reads.  You can find exiftool's GPS source code here.
Troubleshooting hints:
* When posting, include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).
* Double all percent signs (%) in a Windows batch file.
* If your GPS coords are negative, make sure and set the GpsLatitudeRef and GpsLongitudeRef tags correctly.

TheStingPilot

  • Newbie
  • *
  • Posts: 6
Re: Extracting GPS information from a JPG file
« Reply #8 on: July 13, 2020, 08:40:01 AM »
Hello all,

Solved it, and that is thanks to StarGeeks and Phil's input. There is a difference in the Signed and Unsigned result. A 'signed' returns a negative value, an 'unsigned' positive result. The byte value is calculated differently.

I will update this post with evidence later.

With kind regards,
TheStingPilot

TheStingPilot

  • Newbie
  • *
  • Posts: 6
Re: Extracting GPS information from a JPG file
« Reply #9 on: July 13, 2020, 10:10:49 AM »
Hello,

The update. Changing the from Int32 to UInt32 was the big trick.

I like log files. So my script creates an extensive log file. A part of it:

Code: [Select]
47 / 1 = 47
33 / 1 = 33
2194586366 / 100000000 = 21.94586366

     --- Overview of the EXIF GPS Data ---
     --- ID 2 of WP_20170426_15_30_51_Pro.jpg
       Number:                     0
       Value:                      47
       Type:                       byte
       Decimal value (Signed)    : 47
       Decimal value (Unsigned)  : 47
       Remark:                     Deg1
       ---------------------------------------------------------------------
       Number:                     4
       Value:                      1
       Type:                       byte
       Decimal value (Signed)    : 1
       Decimal value (Unsigned)  : 1
       Remark:                     Deg2
       ---------------------------------------------------------------------
       Number:                     8
       Value:                      33
       Type:                       byte
       Decimal value (Signed)    : 33
       Decimal value (Unsigned)  : 33
       Remark:                     Min1
       ---------------------------------------------------------------------
       Number:                     12
       Value:                      1
       Type:                       byte
       Decimal value (Signed)    : 1
       Decimal value (Unsigned)  : 1
       Remark:                     Min2
       ---------------------------------------------------------------------
       Number:                     16
       Value:                      254
       Type:                       byte
       Decimal value (Signed)    : -2100380930
       Decimal value (Unsigned)  : 2194586366
       Remark:                     Sec1
       ---------------------------------------------------------------------
       Number:                     20
       Value:                      0
       Type:                       byte
       Decimal value (Signed)    : 100000000
       Decimal value (Unsigned)  : 100000000
       Remark:                     Sec2
       ---------------------------------------------------------------------
7 / 1 = 7
35 / 1 = 35
3036714792 / 100000000 = 30.36714792

     --- Overview of the EXIF GPS Data ---
     --- ID 4 of WP_20170426_15_30_51_Pro.jpg
       Number:                     0
       Value:                      7
       Type:                       byte
       Decimal value (Signed)    : 7
       Decimal value (Unsigned)  : 7
       Remark:                     Deg1
       ---------------------------------------------------------------------
       Number:                     4
       Value:                      1
       Type:                       byte
       Decimal value (Signed)    : 1
       Decimal value (Unsigned)  : 1
       Remark:                     Deg2
       ---------------------------------------------------------------------
       Number:                     8
       Value:                      35
       Type:                       byte
       Decimal value (Signed)    : 35
       Decimal value (Unsigned)  : 35
       Remark:                     Min1
       ---------------------------------------------------------------------
       Number:                     12
       Value:                      1
       Type:                       byte
       Decimal value (Signed)    : 1
       Decimal value (Unsigned)  : 1
       Remark:                     Min2
       ---------------------------------------------------------------------
       Number:                     16
       Value:                      40
       Type:                       byte
       Decimal value (Signed)    : -1258252504
       Decimal value (Unsigned)  : 3036714792
       Remark:                     Sec1
       ---------------------------------------------------------------------
       Number:                     20
       Value:                      0
       Type:                       byte
       Decimal value (Signed)    : 100000000
       Decimal value (Unsigned)  : 100000000
       Remark:                     Sec2
       ---------------------------------------------------------------------
47.5560960732389
7.5917686522
47º 33' 22" N
7º 35' 30" E

And the two functions that take care of it:

Code: [Select]
Function Get-GPSDetails
 {
 
     <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       13-July-2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-GPSDetails
    =============================================================================================================================================
    .SYNOPSIS

    This function reads the latitude and longitude data from a JPG file. More information can be found at:
    http://www.forensicexpedition.com/2017/08/03/imagemapper-a-powershell-metadata-and-geo-maping-tool-for-images/

    More information about the EXIF layout can be found at: https://exiftool.org/TagNames/GPS.html

    #>
 
    param
     (
      [int]    $ID,
      [String] $FileNameWithGPSDetails
     )

    $img                 = New-Object -TypeName system.drawing.bitmap -ArgumentList $FileNameWithGPSDetails
    $IMGPropertyItems    = $img.PropertyItems | Where {($_.ID -eq $ID)}
    [Double]$Deg         = 0
    [Double]$Min         = 0
    [Double]$Sec         = 0
    $GPSTable            = @()

 
    For($a=0;$a -le 20;$a++)
     {
     
      $GPSRecord  = [ordered] @{"Number"                   = "";
                                "Value"                    = "";
                                "Type"                     = "";
                                "Decimal value (Signed)"   = "";
                                "Decimal value (Unsigned)" = "";
                                "Remark"                   = ""
                                }
     
      Switch ($a)
       {
        "0"  {$Remark = "Deg1"; Break}
        "4"  {$Remark = "Deg2"; Break}
        "8"  {$Remark = "Min1"; Break}
        "12" {$Remark = "Min2"; Break}
        "16" {$Remark = "Sec1"; Break}
        "20" {$Remark = "Sec2"; Break}
        Default {$Remark = ""}
       }
     
      $GPSRecord."Number"                   = $a
      $GPSRecord."Value"                    = $IMGPropertyItems.Value[$a]
      $GPSRecord."Type"                     = $IMGPropertyItems.Value[$a].Gettype()
      $GPSRecord."Decimal value (Signed)"   = ([System.BitConverter]::ToInt32($img.GetPropertyItem($ID).Value, $a))
      $GPSRecord."Decimal value (Unsigned)" = ([System.BitConverter]::ToUInt32($img.GetPropertyItem($ID).Value, $a))
      $GPSRecord."Remark"                   = $Remark
      $objGPSRecord                         = New-Object PSObject -Property $GPSRecord
      $GPSTable                            += $objGPSRecord
    }
                   
    [Double]$Deg1 = ([Decimal][System.BitConverter]::ToUInt32($img.GetPropertyItem($ID).Value, 0))
    [Double]$Deg2 = ([Decimal][System.BitConverter]::ToUInt32($img.GetPropertyItem($ID).Value, 4))
    [Double]$Deg = $Deg1 / $Deg2

    [Double]$Min1 = ([Decimal][System.BitConverter]::ToUInt32($img.GetPropertyItem($ID).Value, 8))
    [Double]$Min2 = ([Decimal][System.BitConverter]::ToUInt32($img.GetPropertyItem($ID).Value, 12))
    [Double]$Min  = $Min1 / $Min2

    [Double]$Sec1 = ([Decimal][System.BitConverter]::ToUInt32($img.GetPropertyItem($ID).Value, 16))
    [Double]$Sec2 = ([Decimal][System.BitConverter]::ToUInt32($img.GetPropertyItem($ID).Value, 20))
    [Double]$Sec = $Sec1 / $Sec2

    Write-Host "$Deg1 / $Deg2 = $Deg"
    Write-Host "$Min1 / $Min2 = $Min"
    Write-Host "$Sec1 / $Sec2 = $Sec"

    Write-Host ""
    Write-Host "     --- Overview of the EXIF GPS Data ---"
    Write-Host "     --- ID $ID of $(Split-Path -Leaf $FileNameWithGPSDetails)"
    ForEach ($object in $GPSTable)
     {
      if($object."Remark")
       {
        Write-Host "       Number:                     $($object."Number")"
        Write-Host "       Value:                      $($object."Value")"
        Write-Host "       Type:                       $($object."Type")"
        Write-Host "       Decimal value (Signed)    : $($object."Decimal value (Signed)")"
        Write-Host "       Decimal value (Unsigned)  : $($object."Decimal value (Unsigned)")"
        Write-Host "       Remark:                     $($object."Remark")"
        Write-Host "       ---------------------------------------------------------------------"
       }
     }
    $GPSTable.Clear()
   
    Return [Double]$Deg, [Double]$Min, [Double]$Sec
 }


Function Get-EXIFDataFromJPGFile
   {

    <#
    .NOTES
    =============================================================================================================================================
    Created with:     Windows PowerShell ISE
    Created on:       06-July-2020
    Created by:       Willem-Jan Vroom
    Organization:     
    Functionname:     Get-EXIFDataFromJPGFile
    =============================================================================================================================================
    .SYNOPSIS

    This function reads the latitude and longitude data from a JPG file.
    If no valid data is found, the return codes will be 1024 and 1024.
    This code is based on
    http://www.forensicexpedition.com/2017/08/03/imagemapper-a-powershell-metadata-and-geo-maping-tool-for-images/

    More information about the EXIF layout can be found at: https://exiftool.org/TagNames/GPS.html

    #>

    Param
     (
      [String] $FileName
     )
   
   
    $img     = New-Object -TypeName system.drawing.bitmap -ArgumentList $FileName
    $Encode  = New-Object System.Text.ASCIIEncoding
    $GPSInfo = $true
    $GPSLat  = ""
    $GPSLon  = ""
     
    # =============================================================================================================================================
    # Try to get the latitude (N or S) from the image.
    # If not successfull then this information is not in the image
    # and quit with the numbers 1024 and 1024.
    # =============================================================================================================================================

    Try
     {
     
      $LatNS = $Encode.GetString($img.GetPropertyItem(1).Value)
     }
      Catch
     {
      $GPSInfo = $False
     }
               
    If ($GPSInfo -eq $true)
     {
      $LonEW = $Encode.GetString($img.GetPropertyItem(3).Value)
     
      [Double]$LatDeg, [Double]$LatMin, [Double]$LatSec = Get-GPSDetails -FileNameWithGPSDetails $FileName -ID 2
      [Double]$LonDeg, [Double]$LonMin, [Double]$LonSec = Get-GPSDetails -FileNameWithGPSDetails $FileName -ID 4
   
      if([Double]$LatMin -lt 0 -or [Double]$LatSec -lt 0 -or [Double]$LonMin -lt 0 -or [Double]$LonSec -lt 0)
       {
        $Alert = $true
        Write-Verbose "    * Error: The picture $FileName has incorrect GPS Data. An alert has been created, it will be mentioned on the HTML page."
      }

      $GPSLat = "$([int]$LatDeg)º $([int]$LatMin)' $([int]$LatSec)$([char]34) $LatNS"
      $GPSLon = "$([int]$LonDeg)º $([int]$LonMin)' $([int]$LonSec)$([char]34) $LonEW"

      Write-Verbose "    The picture $FileName has the following GPS coordinates:"
      Write-Verbose "       $GPSLat"       
      Write-Verbose "       $GPSLon"

    # =============================================================================================================================================
    # Convert the latitude and longitude to numbers that Google Maps recognizes.
    # =============================================================================================================================================

      $LatOrt = 0
      $LonOrt = 0

      If ($LatNS -eq 'S')
       {
        $LatOrt = "-"   
       }
      If ($LonEW -eq 'W')
       {
        $LonOrt = "-"
       }

      $LatDec = ($LatDeg + ($LatMin/60) + ($LatSec/3600))
      $LonDec = ($LonDeg + ($LonMin/60) + ($LonSec/3600))

      $LatOrt = $LatOrt + $LatDec
      $LonOrt = $LonOrt + $LonDec

    # =============================================================================================================================================
    # The numbers that where returned contained a decimal comma instead of a decimal point.
    # So the en-US culture is forced to get the correct number notation.
    # =============================================================================================================================================
   
      $LatOrt = $LatOrt.ToString([cultureinfo]::GetCultureInfo('en-US'))
      $LonOrt = $LonOrt.ToString([cultureinfo]::GetCultureInfo('en-US'))

      Write-Verbose "    The picture $FileName has the following decimal coordinates:"
      Write-Verbose "      $LatOrt"
      Write-Verbose "      $LonOrt"
    }
     else
    {
     
   # =============================================================================================================================================
   # Ohoh... No GPS information in this picture.
   # =============================================================================================================================================
     
     Write-Verbose "    The picture $FileName does not contain GPS information."
     $LatOrt = "1024"
     $LonOrt = "1024"
    }

    Return $LatOrt,$LonOrt,$GPSLat,$GPSLon
  }

  # =============================================================================================================================================
  # Add assemblies.
  # =============================================================================================================================================
 
  Clear-Host

   
  Add-Type -AssemblyName System.Web
  Add-Type -AssemblyName System.Drawing
 
  Get-EXIFDataFromJPGFile -FileName "C:\tmp\WP_20170426_15_30_51_Pro.jpg"

So thanks for Stargeek and Phil for your help. It is appreciated.

With kind regards,
TheStingPilot



YYS

  • Newbie
  • *
  • Posts: 1
Re: Extracting GPS information from a JPG file
« Reply #10 on: August 23, 2020, 01:03:07 PM »
Hello everyone !
Need a bit of help down here )
Cant extract GPS data from a jpg file, it shows me everything exept things that i need )
Could you help me with that ?)

StarGeek

  • Global Moderator
  • ExifTool Freak
  • *****
  • Posts: 4064
Re: Extracting GPS information from a JPG file
« Reply #11 on: August 23, 2020, 01:06:24 PM »
Run this command on the file
exiftool -g1 -a -s -GPS* /path/to/file/

If it doesn't show any GPS coordinates, then they simply don't exist in that file.
Troubleshooting hints:
* When posting, include your OS, Exiftool version, and type of file you're processing (MP4, JPG, etc).
* Double all percent signs (%) in a Windows batch file.
* If your GPS coords are negative, make sure and set the GpsLatitudeRef and GpsLongitudeRef tags correctly.

Hyddo

  • Newbie
  • *
  • Posts: 3
Re: Extracting GPS information from a JPG file
« Reply #12 on: September 17, 2020, 09:17:39 AM »
Thank you for this tip "exiftool -g1 -a -s -GPS* /path/to/file/", it worked perfectly in my case. I was stuck with this jpg file on the pc in my greek flat. Now it's finally sorted.

Hyddo

  • Newbie
  • *
  • Posts: 3
Re: Extracting GPS information from a JPG file
« Reply #13 on: September 23, 2020, 05:41:08 AM »
Thank you for this tip "exiftool -g1 -a -s -GPS* /path/to/file/", it worked perfectly in my case. I was stuck with this jpg file on the pc in my greek flat. Now it's finally sorted.

Seems like I have another issue, I will describe it in a new thread in a bit