PHP extract GPS EXIF data

前端 未结 13 1395
执笔经年
执笔经年 2020-11-29 16:26

I would like to extract the GPS EXIF tag from pictures using php. I\'m using the exif_read_data() that returns a array of all tags + data :

GPS.         


        
相关标签:
13条回答
  • 2020-11-29 16:36

    I'm using the modified version from Gerald Kaszuba but it's not accurate. so i change the formula a bit.

    from:

    return $flip * ($degrees + $minutes / 60);
    

    changed to:

    return floatval($flip * ($degrees +($minutes/60)+($seconds/3600)));
    

    It works for me.

    0 讨论(0)
  • 2020-11-29 16:37

    To get the altitude value, you can use the following 3 lines:

    $data     = exif_read_data($path_to_your_photo, 0, TRUE);
    $alt      = explode('/', $data["GPS"]["GPSAltitude"]);
    $altitude = (isset($alt[1])) ? ($alt[0] / $alt[1]) : $alt[0];
    
    0 讨论(0)
  • 2020-11-29 16:45

    This is a javascript port of the PHP-code posted @Gerald above. This way you can figure out the location of an image without ever uploading the image, in conjunction with libraries like dropzone.js and Javascript-Load-Image

    define(function(){
    
        function parseExif(map) {
            var gps = {
                lng : getGps(map.get('GPSLongitude'), data.get('GPSLongitudeRef')),
                lat : getGps(map.get('GPSLatitude'), data.get('GPSLatitudeRef'))
            }
            return gps;
        }
    
        function getGps(exifCoord, hemi) {
            var degrees = exifCoord.length > 0 ? parseFloat(gps2Num(exifCoord[0])) : 0,
                minutes = exifCoord.length > 1 ? parseFloat(gps2Num(exifCoord[1])) : 0,
                seconds = exifCoord.length > 2 ? parseFloat(gps2Num(exifCoord[2])) : 0,
                flip = (/w|s/i.test(hemi)) ? -1 : 1;
            return flip * (degrees + (minutes / 60) + (seconds / 3600));
        }
    
        function gps2Num(coordPart) {
            var parts = (""+coordPart).split('/');
            if (parts.length <= 0) {
                return 0;
            }
            if (parts.length === 1) {
                return parts[0];
            }
            return parts[0] / parts[1];
        }       
    
        return {
            parseExif: parseExif
        };
    
    });
    
    0 讨论(0)
  • 2020-11-29 16:46

    I know this question has been asked a long time ago, but I came across it while searching in google and the solutions proposed here did not worked for me. So, after further searching, here is what worked for me.

    I'm putting it here so that anybody who comes here through some googling, can find different approaches to solve the same problem:

    function triphoto_getGPS($fileName, $assoc = false)
    {
        //get the EXIF
        $exif = exif_read_data($fileName);
    
        //get the Hemisphere multiplier
        $LatM = 1; $LongM = 1;
        if($exif["GPSLatitudeRef"] == 'S')
        {
        $LatM = -1;
        }
        if($exif["GPSLongitudeRef"] == 'W')
        {
        $LongM = -1;
        }
    
        //get the GPS data
        $gps['LatDegree']=$exif["GPSLatitude"][0];
        $gps['LatMinute']=$exif["GPSLatitude"][1];
        $gps['LatgSeconds']=$exif["GPSLatitude"][2];
        $gps['LongDegree']=$exif["GPSLongitude"][0];
        $gps['LongMinute']=$exif["GPSLongitude"][1];
        $gps['LongSeconds']=$exif["GPSLongitude"][2];
    
        //convert strings to numbers
        foreach($gps as $key => $value)
        {
        $pos = strpos($value, '/');
        if($pos !== false)
        {
            $temp = explode('/',$value);
            $gps[$key] = $temp[0] / $temp[1];
        }
        }
    
        //calculate the decimal degree
        $result['latitude'] = $LatM * ($gps['LatDegree'] + ($gps['LatMinute'] / 60) + ($gps['LatgSeconds'] / 3600));
        $result['longitude'] = $LongM * ($gps['LongDegree'] + ($gps['LongMinute'] / 60) + ($gps['LongSeconds'] / 3600));
    
        if($assoc)
        {
        return $result;
        }
    
        return json_encode($result);
    }
    
    0 讨论(0)
  • 2020-11-29 16:52

    This is my modified version. The other ones didn't work for me. It will give you the decimal versions of the GPS coordinates.

    The code to process the EXIF data:

    $exif = exif_read_data($filename);
    $lon = getGps($exif["GPSLongitude"], $exif['GPSLongitudeRef']);
    $lat = getGps($exif["GPSLatitude"], $exif['GPSLatitudeRef']);
    var_dump($lat, $lon);
    

    Prints out in this format:

    float(-33.8751666667)
    float(151.207166667)
    

    Here are the functions:

    function getGps($exifCoord, $hemi) {
    
        $degrees = count($exifCoord) > 0 ? gps2Num($exifCoord[0]) : 0;
        $minutes = count($exifCoord) > 1 ? gps2Num($exifCoord[1]) : 0;
        $seconds = count($exifCoord) > 2 ? gps2Num($exifCoord[2]) : 0;
    
        $flip = ($hemi == 'W' or $hemi == 'S') ? -1 : 1;
    
        return $flip * ($degrees + $minutes / 60 + $seconds / 3600);
    
    }
    
    function gps2Num($coordPart) {
    
        $parts = explode('/', $coordPart);
    
        if (count($parts) <= 0)
            return 0;
    
        if (count($parts) == 1)
            return $parts[0];
    
        return floatval($parts[0]) / floatval($parts[1]);
    }
    
    0 讨论(0)
  • 2020-11-29 16:52

    This is an old question but felt it could use a more eloquent solution (OOP approach and lambda to process the fractional parts)

    /**
     * Example coordinate values
     *
     * Latitude - 49/1, 4/1, 2881/100, N
     * Longitude - 121/1, 58/1, 4768/100, W
     */
    protected function _toDecimal($deg, $min, $sec, $ref) {
    
        $float = function($v) {
            return (count($v = explode('/', $v)) > 1) ? $v[0] / $v[1] : $v[0];
        };
    
        $d = $float($deg) + (($float($min) / 60) + ($float($sec) / 3600));
        return ($ref == 'S' || $ref == 'W') ? $d *= -1 : $d;
    }
    
    
    public function getCoordinates() {
    
        $exif = @exif_read_data('image_with_exif_data.jpeg');
    
        $coord = (isset($exif['GPSLatitude'], $exif['GPSLongitude'])) ? implode(',', array(
            'latitude' => sprintf('%.6f', $this->_toDecimal($exif['GPSLatitude'][0], $exif['GPSLatitude'][1], $exif['GPSLatitude'][2], $exif['GPSLatitudeRef'])),
            'longitude' => sprintf('%.6f', $this->_toDecimal($exif['GPSLongitude'][0], $exif['GPSLongitude'][1], $exif['GPSLongitude'][2], $exif['GPSLongitudeRef']))
        )) : null;
    
    }
    
    0 讨论(0)
提交回复
热议问题