Quantcast
Channel: Xamarin.Forms — Xamarin Community Forums
Viewing all articles
Browse latest Browse all 58056

Is it possible to retain a picture's metadata after resizing the image and saving to app directory?

$
0
0

Hello, I am using the MediaPicker.TakePhoto() method to capture a picture from the user's device, then I am resizing the picture and saving within the app's local storage.

What I would like to do is to retain the photo's EXIF (metadata) information, such as date taken, geolocation, etc. Is this possible?

Here's my code, including the resize function:

        /// <summary>
        /// Raises the photo received event. This is called when the photo is selected
        /// from the gallery or captured by the camera.
        /// </summary>
        /// <param name="file">File.</param>
        private void OnPhotoReceived(IMediaFile file) {
            if (file == null) {
                ShowInfoDialog ("Photo canceled", "Camera");
            } else {
                UIImage photo = null;
                /*var photo = ImageSource.FromFile (file.Path);
                if (photo != null)
                    photo = MaxResizeImage (photo, 800, 800);
                this.Photo = photo;*/
                photo = UIImage.FromFile (file.Path);
                var randomInt = Convert.ToUInt64 (new Random ().NextDouble () * UInt64.MaxValue);
                var name = randomInt + ".jpg";
                var documentsDirectory = QCApp.MediaPath;
                string jpgFilename = System.IO.Path.Combine (documentsDirectory, name); // hardcoded filename, overwritten each time
                // Resize the photo!
                photo = MaxResizeImage (photo, 800, 800);
                NSData imgData = photo.AsJPEG ();
                NSError err = null;
                if (imgData.Save (jpgFilename, false, out err)) {
                    System.Diagnostics.Debug.WriteLine ("saved as " + jpgFilename);
                    // Save info to Pictures collection.
                    Pictures.Add (new Picture {
                        Path = jpgFilename,
                        Filename = name,
                        SurveyColumnId = this.CurrentQuestionId,
                        SectionId = this.SelectedModel.Id,
                        IsUploaded = false,
                        SurveyId = this.SurveyId,
                        SerialNumber = this.CurrentSerialNumber
                    });
                    MessagingCenter.Send (this, string.Format(PictureMessageCenterFormat, this.CurrentQuestionId, this.CurrentSerialNumber));
                    //this.OnPropertyChanged ("Pictures");
                } else {
                    System.Diagnostics.Debug.WriteLine ("NOT saved as " + jpgFilename + " because" + err.LocalizedDescription);
                }
            }
        }

        /// <summary>
        /// Uploads the picture to Azure.
        /// </summary>
        /// <returns>The picture.</returns>
        /// <param name="picture">Picture.</param>
        public async Task<CloudBlockBlob> UploadPicture(Picture picture) {
            return await UploadImage (picture);
        }

        static CloudBlobClient GetClient ()
        {
            var creds = new StorageCredentials (Constants.AZURE_BLOB_ACCOUNTNAME, Constants.AZURE_BLOB_KEYVALUE);
            var client = new CloudStorageAccount (creds, true).CreateCloudBlobClient ();
            return client;
        }

        private async Task<CloudBlockBlob> UploadImage(Picture picture) 
        {
            try {
                if (!string.IsNullOrWhiteSpace(picture.Path) && !picture.IsUploaded) {
                    var photo = UIImage.FromFile (picture.Path);
                    var client = GetClient ();
                    var container = client.GetContainerReference("surveypics");
                    container.CreateIfNotExists();
                    var blob = container.GetBlockBlobReference(picture.Filename);
                    var jpgImage = photo.AsJPEG ();
                    var stream = jpgImage.AsStream();

                    blob.UploadFromStream (stream);

                    return blob;
                }
                else
                    return null;
            }
            catch (Microsoft.WindowsAzure.Storage.StorageException storageException)
            {
                return null;
            }
            catch (System.Net.ProtocolViolationException protocolViolationException)
            {
                return null;
            }
            catch (Exception e) {
                MessagingCenter.Send<MobileServiceClient, ExceptionContainerException> (QCApp.Client, 
                    Common.Constants.MessageCenterMessages.MessagingCenterError, new ExceptionContainerException { Title = "Error uploading image",
                        Exception = e
                    });
                return null;
            }
        }

        // Resize the image to be contained within a maximum width and height, keeping aspect ratio:
        public UIImage MaxResizeImage(UIImage sourceImage, float maxWidth, float maxHeight)
        {
            var sourceSize = sourceImage.Size;
            var maxResizeFactor = Math.Min(maxWidth / sourceSize.Width, maxHeight / sourceSize.Height);
            if (maxResizeFactor > 1) return sourceImage;
            var width = maxResizeFactor * sourceSize.Width;
            var height = maxResizeFactor * sourceSize.Height;
            UIGraphics.BeginImageContext(new SizeF(width, height));
            sourceImage.Draw(new RectangleF(0, 0, width, height));
            var resultImage = UIGraphics.GetImageFromCurrentImageContext();
            UIGraphics.EndImageContext();
            return resultImage;
        }

Viewing all articles
Browse latest Browse all 58056

Trending Articles