DESCRIPTION: With two days before deadline I find out and confirmed by Stuart that picture taken with TakePicture method does not save the Geo location.
WORKS:
1. The picture is taken with TakePicture and it's saved
2. The lat and lng are detected and sent to each platform implementation
3. The fileName is sent from core after picture is saved to implementations
4. The platform implementations are including the Geo Tags into the picture
5. The image upload works, sending the geo tags
THE CODE WHICH ADDS THE GEO TAGGING TO PICTURE :
ANDROID (UPDATE: WORKING):
public bool SaveImageWithGpsTags(string fileName, double lat, double lng)
{
var context = Mvx.Resolve<IMvxAndroidGlobals>().ApplicationContext;
var fullPath = Path.Combine(context.FilesDir.Path, fileName);
if (!File.Exists(fullPath)) return false;
try
{
using (var ef = new ExifInterface(fullPath))
{
ef.SetAttribute(ExifInterface.TagGpsLatitude, Dec2Dms(lat));
ef.SetAttribute(ExifInterface.TagGpsLongitude, Dec2Dms(lng));
ef.SetAttribute(ExifInterface.TagGpsLatitudeRef, lat > 0 ? "N" : "S");
ef.SetAttribute(ExifInterface.TagGpsLongitudeRef, lng > 0 ? "E" : "W");
ef.SaveAttributes();
}
}
catch (Exception e)
{
return false;
}
}
static String Dec2Dms(double coord)
{
coord = coord > 0 ? coord : -coord; // -105.9876543 -> 105.9876543
var sOut = string.Format("{0}/1,", ((int)coord)); // 105/1,
coord = (coord % 1) * 60; // .987654321 * 60 = 59.259258
sOut = sOut + string.Format("{0}/1,", ((int)coord)); // 105/1,59/1,
coord = (coord % 1) * 60000; // .259258 * 60000 = 15555
sOut = sOut + string.Format("{0}/1000,", ((int)coord)); // 105/1,59/1,15555/1000
return sOut;
}
TOUCH (UPDATE: WORKING):
const string resScheme = "res:";
var imagePath = fileName.StartsWith(resScheme) ? fileName.Substring(resScheme.Length) : Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments), fileName);
var originalImage = UIImage.FromFile(imagePath);
var gpsDict = new NSMutableDictionary();
var imageMetadata = new NSMutableDictionary();
gpsDict.SetValueForKey(NSObject.FromObject(lng), new NSString("Longitude"));
gpsDict.SetValueForKey(NSObject.FromObject(lng > 0 ? "E" : "W"), new NSString("LongitudeRef"));
gpsDict.SetValueForKey(NSObject.FromObject(lat), new NSString("Latitude"));
gpsDict.SetValueForKey(NSObject.FromObject(lat > 0 ? "N" : "S"), new NSString("LatitudeRef"));
gpsDict.SetValueForKey(NSObject.FromObject(DateTime.UtcNow.ToString("HH:MM:ss.ff")), new NSString("TimeStamp"));
imageMetadata.SetValueForKey (gpsDict as NSDictionary, MonoTouch.ImageIO.CGImageProperties.GPSDictionary);
var imgSrc = CGImageSource.FromData (originalImage.AsJPEG ());
var outImageData = new NSMutableData();
using (
var d = CGImageDestination.FromData(outImageData, imgSrc.TypeIdentifier, 1,
new CGImageDestinationOptions()))
{
d.AddImage (imgSrc, imgSrc.ImageCount - 1, imageMetadata);
d.Close();
}
NSError writeError;
var imageSaved = outImageData.Save(imagePath, NSDataWritingOptions.Atomic, out writeError);
if (client.DefaultRequestHeaders.CacheControl == null)
client.DefaultRequestHeaders.CacheControl = new CacheControlHeaderValue();
client.DefaultRequestHeaders.CacheControl.NoCache = true;
client.DefaultRequestHeaders.CacheControl.NoStore = true;
byte[] imageBytes;
var result = Mvx.Resolve<IMvxFileStore>().TryReadBinaryFile(imagePath, out imageBytes);
var fileContent = new ByteArrayContent(imageBytes,0,imageBytes.Count());
var fileName = NewGuid() + ".jpg";
const string reference = "picture"
fileContent.Headers.ContentType = MediaTypeHeaderValue.Parse("multipart/form-data");
fileContent.Headers.ContentDisposition = new ContentDispositionHeaderValue("form-data")
{
FileName = fileName,
Name = reference,
};
content.Add(fileContent);
content.Add(new StringContent(Settings.UserId), "userid");
await client.PostAsync("SOME SERVER URL", content);
Everyone who is interested in the solution will find the answer in the question itself updated!
Sorry Cheesebaron, I didn't know!