How to read the GPS information with all decimal part of its second from the photo?

Allen PPL 5 Reputation points
2023-02-02T00:47:47.74+00:00

Here is my C# code.

private void ReadExifGPS()

    {

        var ofd = new OpenFileDialog();

        ofd.Filter = ".jpg|.jpg";

        if (ofd.ShowDialog() == DialogResult.OK)

        {


           

            Image objImage = Image.FromFile(ofd.FileName);


           

            var propertyItems = objImage.PropertyItems.OrderBy(x => x.Id);

            foreach (PropertyItem objItem in propertyItems)

            {

                switch (objItem.Id)

                {

                    case 0x0002:

                        if (objItem.Value.Length == 24)

                        {

                            //degrees  

                            double d = BitConverter.ToUInt32(objItem.Value, 0) * 1.0d / BitConverter.ToUInt32(objItem.Value, 4);

                            //minutes

                            double m = BitConverter.ToUInt32(objItem.Value, 8) * 1.0d / BitConverter.ToUInt32(objItem.Value, 12);

                            //seconds 

                            var s1 = BitConverter.ToUInt32(objItem.Value, 16);

                            var s2 = BitConverter.ToUInt32(objItem.Value, 20);

                            double s = (double)s1 / (double)s2;

                            //double s = BitConverter.ToUInt32(objItem.Value, 16) * 1.0d / BitConverter.ToUInt32(objItem.Value, 20);


                           

                            double dblGPSLatitude = (((s / 60 + m) / 60) + d) ;

                            //rtbMsg.Text += "Latitude: " + string.Format("{0:#};{1:#};{2:#.00};{3}", d, m, s, chrGPSLatitudeRef) + Environment.NewLine;

                            rtbMsg.Text += "Latitude: " + string.Format("{0};{1};{2}", d, m, s) + Environment.NewLine;

                        }

                        break;

                    case 0x0004:

                        if (objItem.Value.Length == 24)

                        {

                            //degrees  

                            double d = BitConverter.ToUInt32(objItem.Value, 0) * 1.0d / BitConverter.ToUInt32(objItem.Value, 4);

                            //minutes 

                            double m = BitConverter.ToUInt32(objItem.Value, 8) * 1.0d / BitConverter.ToUInt32(objItem.Value, 12);

                            //seconds  

                            var s1 = BitConverter.ToUInt32(objItem.Value, 16);

                            var s2 = BitConverter.ToUInt32(objItem.Value, 20);

                            double s = (double)s1 / (double)s2;


                             

                            double dblGPSLongitude = (((s / 60 + m) / 60) + d);

                            rtbMsg.Text += "Longitude: " + string.Format("{0};{1};{2}", d, m, s) + Environment.NewLine;

                        }

                        break;

                    default:

                        break;

                }

            }

        }

    }

Run the Code will get :

Latitude: 39;59;8.27

Longitude: 116;17;34.74

照片GPS信息

You can see it's different from the win system info panel.

How can I get all decimal part?

Thanks in advantage!

C#
C#
An object-oriented and type-safe programming language that has its roots in the C family of languages and includes support for component-oriented programming.
9,936 questions
{count} votes

1 answer

Sort by: Most helpful
  1. Reza Aghaei 4,931 Reputation points MVP
    2023-02-02T01:08:28.87+00:00

    There's an answer for this question here: Getting GPS data from an image's EXIF in C# one clean suggestion is:

    public static float? GetLatitude(Image targetImg)
    {
        try
        {
            //Property Item 0x0001 - PropertyTagGpsLatitudeRef
            PropertyItem propItemRef = targetImg.GetPropertyItem(1);
            //Property Item 0x0002 - PropertyTagGpsLatitude
            PropertyItem propItemLat = targetImg.GetPropertyItem(2);
            return ExifGpsToFloat(propItemRef, propItemLat);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
    public static float? GetLongitude(Image targetImg)
    {
        try
        {
            ///Property Item 0x0003 - PropertyTagGpsLongitudeRef
            PropertyItem propItemRef = targetImg.GetPropertyItem(3);
            //Property Item 0x0004 - PropertyTagGpsLongitude
            PropertyItem propItemLong = targetImg.GetPropertyItem(4);
            return ExifGpsToFloat(propItemRef, propItemLong);
        }
        catch (ArgumentException)
        {
            return null;
        }
    }
    private static float ExifGpsToFloat(PropertyItem propItemRef, PropertyItem propItem)
    {
        uint degreesNumerator = BitConverter.ToUInt32(propItem.Value, 0);
        uint degreesDenominator = BitConverter.ToUInt32(propItem.Value, 4);
        float degrees = degreesNumerator / (float)degreesDenominator;
    
        uint minutesNumerator = BitConverter.ToUInt32(propItem.Value, 8);
        uint minutesDenominator = BitConverter.ToUInt32(propItem.Value, 12);
        float minutes = minutesNumerator / (float)minutesDenominator;
    
        uint secondsNumerator = BitConverter.ToUInt32(propItem.Value, 16);
        uint secondsDenominator = BitConverter.ToUInt32(propItem.Value, 20);
        float seconds = secondsNumerator / (float)secondsDenominator;
    
        float coorditate = degrees + (minutes / 60f) + (seconds / 3600f);
        string gpsRef = System.Text.Encoding.ASCII.GetString(new byte[1]  { propItemRef.Value[0] } ); //N, S, E, or W
        if (gpsRef == "S" || gpsRef == "W")
            coorditate = 0 - coorditate;
        return coorditate;
    }
    
    2 people found this answer helpful.