将位置坐标写入exif更改位置

时间:2014-07-05 12:18:35

标签: android android-location

我在Google Play上发布了一个应用程序,该应用程序在某个时刻获取用户的地理位置并将其保存为图片。然而,我现在收到一些巴西用户的报告,抱怨这些照片在沙特阿拉伯正在进行GeoTagged。只收到了巴西用户的投诉,我决不能自己重现这个问题。

可能导致此问题的原因是什么?

//我使用这本“书”保存并阅读ExifInterface中的位置..

// Write Geotag and time to Image's Exif
public Boolean writeExifData(Location location, Date date, String filepath){

    // Determine if we got a location
    boolean isLocationOn = false;
    if(location != null){ isLocationOn = true; }

    try {
        // Set up exif 
        ExifInterface exif = new ExifInterface(filepath);

        if(isLocationOn){
            // Get location values
            double latitude = location.getLatitude();
            double longitude = location.getLongitude();
            float accuracy = location.getAccuracy();

            // Convert Latitude and Longitude
            int num1Lat = (int)Math.floor(latitude);
            int num2Lat = (int)Math.floor((latitude - num1Lat) * 60);
            double num3Lat = (latitude - ((double)num1Lat+((double)num2Lat/60))) * 3600000;

            int num1Lon = (int)Math.floor(longitude);
            int num2Lon = (int)Math.floor((longitude - num1Lon) * 60);
            double num3Lon = (longitude - ((double)num1Lon+((double)num2Lon/60))) * 3600000;

            exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE, num1Lat+"/1,"+num2Lat+"/1,"+num3Lat+"/1000");
            exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE, num1Lon+"/1,"+num2Lon+"/1,"+num3Lon+"/1000");

            if (latitude > 0) {
                exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "N"); 
            }else {
                exif.setAttribute(ExifInterface.TAG_GPS_LATITUDE_REF, "S");
            }

            if (longitude > 0) {
                exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "E");    
            }else {
            exif.setAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF, "W");
            }

            // Add accuracy to exif
            String accuracy_value = String.valueOf(Math.round(accuracy));
            exif.setAttribute("UserComment", "accuracy=" + accuracy_value);
        }

        // Add capture time to exif
        exif.setAttribute(ExifInterface.TAG_DATETIME, date.toString());

        // Save exif
        exif.saveAttributes();

        Log.v(Constants.TAG_ALERT_PROCESS, "Wrote data to Exif successfully");
        return true;
    } catch (IOException e) {
        Log.v(Constants.TAG_ALERT_PROCESS, "Failed writing data to Exif with error: " + e.getMessage());
        return false;
    } 
}

public Object_ImageExifData readExifData(String filePath){
    Helper_ExifGeoConverter geoConverter;
    Location location = null;
    ExifInterface exif;

    // Format filePath String (remove "file://" )
    if(filePath.startsWith("file://")){
        filePath = filePath.replace("file://", "");
    }

    try {
        exif = new ExifInterface(filePath);
        if(exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE) != null){

            geoConverter = new Helper_ExifGeoConverter(exif);
            location = new Location("");
            float float_lat = geoConverter.getLatitude();
            location.setLatitude(float_lat);
            float float_lon = geoConverter.getLongitude();
            location.setLongitude(float_lon);

            /** Get accuracy. Accuracy is stored
              * under the tag UserComment as "accuracy=xx"*/
            if(exif.getAttribute("UserComment") != null){
                String value = exif.getAttribute("UserComment");
                value = value.replace("accuracy=", "");
                float accuracy = Integer.parseInt(value);
                location.setAccuracy(accuracy);
            } 

            // Get capture time
            String time = "";
            if(exif.getAttribute(ExifInterface.TAG_DATETIME) != null){
                time = exif.getAttribute(ExifInterface.TAG_DATETIME);
            }

            return new Object_ImageExifData(location, time);
        }else{

            // Get capture time
            String time = "xx.xx.xxxx";
            if(exif.getAttribute(ExifInterface.TAG_DATETIME) != null){
                time = exif.getAttribute(ExifInterface.TAG_DATETIME);
            }

            return new Object_ImageExifData(location, time);
        }

    } catch (IOException e) {
        e.printStackTrace();
        Log.v("myTag", "Failed to read exif data");
        return null;
    }
}

public class Helper_ExifGeoConverter{

    private boolean valid = false;
    Float Latitude, Longitude;

    Helper_ExifGeoConverter(ExifInterface exif) {
        String attrLATITUDE = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE);
        String attrLATITUDE_REF = exif.getAttribute(ExifInterface.TAG_GPS_LATITUDE_REF);
        String attrLONGITUDE = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE);
        String attrLONGITUDE_REF = exif.getAttribute(ExifInterface.TAG_GPS_LONGITUDE_REF);

        if ((attrLATITUDE != null) && (attrLATITUDE_REF != null)
                && (attrLONGITUDE != null) && (attrLONGITUDE_REF != null)) {
            valid = true;

            if (attrLATITUDE_REF.equals("N")) {
                Latitude = convertToDegree(attrLATITUDE);
            } else {
                Latitude = 0 - convertToDegree(attrLATITUDE);
            }

            if (attrLONGITUDE_REF.equals("E")) {
                Longitude = convertToDegree(attrLONGITUDE);
            } else {
                Longitude = 0 - convertToDegree(attrLONGITUDE);
            }

        }
    }

    private Float convertToDegree(String stringDMS){
         Float result;
         String[] DMS = stringDMS.split(",", 3);

         String[] stringD = DMS[0].split("/", 2);
         Double D0 = Double.valueOf(stringD[0]);
         Double D1 = Double.valueOf(stringD[1]);
         Double FloatD = D0/D1;

         String[] stringM = DMS[1].split("/", 2);
         Double M0 = Double.valueOf(stringM[0]);
         Double M1 = Double.valueOf(stringM[1]);
         Double FloatM = M0/M1;

         String[] stringS = DMS[2].split("/", 2);
         Double S0 = Double.valueOf(stringS[0]);
         Double S1 = Double.valueOf(stringS[1]);
         Double FloatS = S0/S1;

         result = new Float(FloatD + (FloatM/60) + (FloatS/3600));

         return result;
    }

在@greenapps的帮助下,我开始意识到,在写入Exif时,我将位置从十进制格式转换为度,分,秒格式错误。改为使用this code

1 个答案:

答案 0 :(得分:0)

如果你将geo lat / lon标签放在jpg的exif信息中,那么所有纬度/经度都是正数。您还必须设置E / O和N / S标记。你在做吗?