cloudacy / native_exif

A simple EXIF metadata reader/writer for Flutter.
MIT License
16 stars 14 forks source link

GPSLatitude and GPSLongitude is not working #3

Closed dnadawa closed 2 years ago

dnadawa commented 2 years ago

I use the below code to update the exif data of a picked image.

Position position = await _determinePosition();

final exif = await Exif.fromPath(_pickedImage!.path);
final file = File('${Directory.systemTemp.path}/temp.jpg');
final imageBytes = await _pickedImage!.readAsBytes();
await file.create();
await file.writeAsBytes(imageBytes);
final attributes = await exif.getAttributes();
final newExif = await Exif.fromPath(file.path);

attributes!['GPSLatitude'] = position.latitude.toString();
attributes['GPSLongitude'] = position.longitude.toString();
attributes['GPSLatitudeRef'] = "N";
attributes['GPSLongitudeRef'] = "E";

await newExif.writeAttributes(attributes);

But it did not add GPSLatitude and GPSLongitude data to the exif data. It only adds GPSLatitudeRef and GPSLongitudeRef.

I am using native_exif: ^0.2.0 package.

d-kuen commented 2 years ago

In case you are using an android device, make sure to write fraction-based values. See https://developer.android.com/reference/android/media/ExifInterface#TAG_GPS_LATITUDE for more details.

Otherwise please let us know on which platform you are testing on and provide some example values, which _determinePosition() returns. Thank you.

dnadawa commented 2 years ago

Previously I used latitude as 6.0183749 and longitude as80.4273429. Then I converted it into the rational format listed in the android documentation and the issue is fixed.

I used the flutter latlong_to_osgrid package to convert lat and long into DMS format and the use following function to create the correct GPSLatitude and GPSLongitude string.

String _decimalToRational(List dmsList){
    return "${dmsList[0].abs()}/1,${dmsList[1]}/1,${(double.parse(dmsList[2].toStringAsFixed(3)) * 1000).toInt()}/1000";
  }

Here is the full code.

Position position = await _determinePosition();

final exif = await Exif.fromPath(_pickedImage!.path);
final attributes = await exif.getAttributes();

//from latlong_to_osgrid package
LatLongConverter converter = LatLongConverter();
List convertedLatitude = converter.getDegreeFromDecimal(position.latitude);
List convertedLongitude = converter.getDegreeFromDecimal(position.longitude);

attributes!['GPSLatitude'] = _decimalToRational(convertedLatitude);
attributes['GPSLongitude'] = _decimalToRational(convertedLongitude);
attributes['GPSLatitudeRef'] = position.latitude > 0 ? "N" : "S";
attributes['GPSLongitudeRef'] = position.longitude > 0 ? "E" : "W";

await exif.writeAttributes(attributes);

P.S. - I only test this on Android.