Last active
March 4, 2021 00:56
-
-
Save baileysh9/7173e8e095ef58ea149c1a4b0cf57699 to your computer and use it in GitHub Desktop.
Handling Images from the Camera and Photo Gallery in Xamarin Android
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
protected override void OnActivityResult(int requestCode, Result resultCode, Intent data) | |
{ | |
base.OnActivityResult(requestCode, resultCode, data); | |
//Camera Request | |
if (requestCode == 0) | |
{ | |
if (resultCode == Result.Ok) | |
{ | |
Task.Run(() => | |
{ | |
if (App.selectedImageId != null) | |
{ | |
var documentsDirectry = Forms.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures); | |
string pngFilename = System.IO.Path.Combine(documentsDirectry.AbsolutePath, App.selectedPetForPhoto.PetId + "." + CoreBag.Models.FileFormatEnum.JPEG.ToString()); | |
if (File.Exists(pngFilename)) | |
{ | |
Java.IO.File file = new Java.IO.File(documentsDirectry, App.selectedImageId + "." + FileFormatEnum.JPEG.ToString()); | |
Android.Net.Uri uri = Android.Net.Uri.FromFile(file); | |
//Read the meta data of the image to determine what orientation the image should be in | |
var originalMetadata = new ExifInterface(pngFilename); | |
int orientation = GetRotation(originalMetadata); | |
var fileName = App.selectedPetForPhoto.PetId + "." + FileFormatEnum.JPEG.ToString(); | |
HandleBitmap(uri, orientation, fileName); | |
} | |
} | |
}); | |
} | |
} | |
else if(requestCode == 1) | |
{ | |
if(resultCode == Result.Ok) | |
{ | |
if (data.Data != null) | |
{ | |
//Grab the Uri which is holding the path to the image | |
Android.Net.Uri uri = data.Data; | |
string fileName = null; | |
if (App.selectedPetForPhoto != null) | |
{ | |
fileName = App.selectedImageId + "." + FileFormatEnum.JPEG.ToString(); | |
var pathToImage = GetPathToImage(uri); | |
var originalMetadata = new ExifInterface(pathToImage); | |
int orientation = GetRotation(originalMetadata); | |
HandleBitmap(uri, orientation, fileName); | |
} | |
} | |
} | |
} | |
} | |
/* | |
* https://stackoverflow.com/questions/26597811/xamarin-choose-image-from-gallery-path-is-null | |
*/ | |
private string GetPathToImage(Android.Net.Uri uri) | |
{ | |
string doc_id = ""; | |
using (var c1 = ContentResolver.Query(uri, null, null, null, null)) | |
{ | |
c1.MoveToFirst(); | |
String document_id = c1.GetString(0); | |
doc_id = document_id.Substring(document_id.LastIndexOf(":") + 1); | |
} | |
string path = null; | |
// The projection contains the columns we want to return in our query. | |
string selection = Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " =? "; | |
using (var cursor = ManagedQuery(Android.Provider.MediaStore.Images.Media.ExternalContentUri, null, selection, new string[] { doc_id }, null)) | |
{ | |
if (cursor == null) return path; | |
var columnIndex = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data); | |
cursor.MoveToFirst(); | |
path = cursor.GetString(columnIndex); | |
} | |
return path; | |
} | |
public int GetRotation(ExifInterface exif) | |
{ | |
try | |
{ | |
var orientation = (Android.Media.Orientation)exif.GetAttributeInt(ExifInterface.TagOrientation, (int)Android.Media.Orientation.Normal); | |
switch (orientation) | |
{ | |
case Android.Media.Orientation.Rotate90: | |
return 90; | |
case Android.Media.Orientation.Rotate180: | |
return 180; | |
case Android.Media.Orientation.Rotate270: | |
return 270; | |
default: | |
return 0; | |
} | |
} | |
catch (Exception ex) | |
{ | |
App.WriteOutput(ex.ToString()); | |
return 0; | |
} | |
} | |
public async Task HandleBitmap(Android.Net.Uri uri, int orientation, string imageId) | |
{ | |
try | |
{ | |
Bitmap mBitmap = Android.Provider.MediaStore.Images.Media.GetBitmap(this.ContentResolver, uri); | |
Bitmap myBitmap = null; | |
if (mBitmap != null) | |
{ | |
//In order to rotate the image we create a Matrix object, rotate if the image is not already in it's correct orientation | |
Matrix matrix = new Matrix(); | |
if (orientation != 0) | |
{ | |
matrix.PreRotate(orientation); | |
} | |
myBitmap = Bitmap.CreateBitmap(mBitmap, 0, 0, mBitmap.Width, mBitmap.Height, matrix, true); | |
MemoryStream stream = new MemoryStream(); | |
//Compressing by 50%, feel free to change if file size is not a factor | |
myBitmap.Compress(Bitmap.CompressFormat.Jpeg, 50, stream); | |
byte[] bitmapData = stream.ToArray(); | |
//Save the image if a file name was supplied. | |
if (imageId != null && imageId != "") | |
{ | |
SavePictureToDisk(myBitmap, imageId); | |
} | |
//Send image byte array back to UI | |
MessagingCenter.Send<byte[]>(bitmapData, "ImageSelected"); | |
} | |
} | |
catch(Exception e) | |
{ | |
App.WriteOutput(e.ToString()); | |
} | |
} | |
public void SavePictureToDisk(Bitmap source, string imageName) | |
{ | |
try | |
{ | |
Task.Run(() => | |
{ | |
var documentsDirectry = Forms.Context.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures); | |
string pngFilename = System.IO.Path.Combine(documentsDirectry.AbsolutePath, imageName); | |
//If the image already exists, delete, and make way for the updated one | |
if (File.Exists(pngFilename)) | |
{ | |
File.Delete(pngFilename); | |
} | |
using (FileStream fs = new FileStream(pngFilename, FileMode.OpenOrCreate)) | |
{ | |
source.Compress(Bitmap.CompressFormat.Jpeg, 50, fs); | |
fs.Close(); | |
} | |
App.WriteOutput("Saved photo"); | |
}); | |
} | |
catch(Exception e) | |
{ | |
App.WriteOutput(e.ToString()); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
does it work with xamarin or dropbox?