How to load image from camera and gallery in Xamarin Image Editor (SfImageEditor)?
This article explains how to load an image from camera / gallery in Syncfusion Xamarin Image Editor (SfImageEditor) with the following procedure.
To take a picture in Xamarin.Forms, you need to use the native platform’s API’s to access the camera. Here, it has been done with help of DependencyService which is implemented across all the platform specific projects.
Here implements CameraInterface interface.
public interface CameraInterface { void LaunchCamera(FileFormatEnum imageType, string imageId = null); void LaunchGallery(FileFormatEnum imageType, string imageId = null); }
Using it, register the DependencyService based on platform specific as per in below
Android:
public void LaunchCamera(FileFormatEnum fileType, string imageId) { var intent = new Intent(MediaStore.ActionImageCapture); Intent takePictureIntent = new Intent(MediaStore.ActionImageCapture); if (takePictureIntent.ResolveActivity(MainActivity.ActivityContext.PackageManager) != null) { try { var documentsDirectry = MainActivity.ActivityContext.GetExternalFilesDir(Android.OS.Environment.DirectoryPictures); cameraFile = new Java.IO.File(documentsDirectry, imageId + "." + fileType.ToString()); if (cameraFile != null) { using (var mediaStorageDir = new Java.IO.File(documentsDirectry, string.Empty)) { if (!mediaStorageDir.Exists()) { if (!mediaStorageDir.Mkdirs()) throw new IOException("Couldn't create directory, have you added the WRITE_EXTERNAL_STORAGE permission?"); } } } } catch (IOException ex) { Console.WriteLine(ex); } //Ensure the authority matches what you put in the AndroidManifest.xml file Android.Net.Uri photoURI = FileProvider.GetUriForFile(((Activity)MainActivity.ActivityContext), "com.yourcompany.IECameraAndGallery.fileprovider", cameraFile); takePictureIntent.PutExtra(MediaStore.ExtraOutput, photoURI); ((Activity)MainActivity.ActivityContext).StartActivityForResult(takePictureIntent, 0); } } public void LaunchGallery(FileFormatEnum fileType, string imageId) { var imageIntent = new Intent(); imageIntent.SetType("image/*"); if (imageId != null) { imageIntent.PutExtra("fileName", imageId + "." + fileType.ToString()); } imageIntent.SetAction(Intent.ActionGetContent); ((Activity)MainActivity.ActivityContext).StartActivityForResult(Intent.CreateChooser(imageIntent, "Select photo"), 1); }
Set the requestLegacyExternalStorage value as true in your app’s manifest file, if the target version is 10.
iOS:
public async void LaunchCamera(FileFormatEnum imageType, string imageId = null) { //Check if we have permission to use the camera var authorizationStatus = AVCaptureDevice.GetAuthorizationStatus(AVMediaType.Video); if (authorizationStatus != AVAuthorizationStatus.Authorized) { var access = await AVCaptureDevice.RequestAccessForMediaTypeAsync(AVMediaType.Video); if (access) { if (imageId == null) GotAccessToCamera(imageType); else { var fileName = imageId + "." + imageType.ToString(); GotAccessToCamera(imageType, fileName); } } } else { if (imageId == null) GotAccessToCamera(imageType); else { var fileName = imageId + "." + imageType.ToString(); GotAccessToCamera(imageType, fileName); } } } public void LaunchGallery(FileFormatEnum imageType, string imageId = null) { try { var imagePicker = new UIImagePickerController { SourceType = UIImagePickerControllerSourceType.PhotoLibrary, MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary) }; imagePicker.AllowsEditing = true; var window = UIApplication.SharedApplication.KeyWindow; var vc = window.RootViewController; while (vc.PresentedViewController != null) { vc = vc.PresentedViewController; } vc.PresentViewController(imagePicker, true, null); imagePicker.FinishedPickingMedia += (sender, e) => { UIImage originalImage = e.Info[UIImagePickerController.EditedImage] as UIImage; if (originalImage != null) { NSData pngImage = null; if (imageType == FileFormatEnum.JPEG) pngImage = originalImage.AsJPEG(); else pngImage = originalImage.AsPNG(); byte[] myByteArray = new byte[pngImage.Length]; System.Runtime.InteropServices.Marshal.Copy(pngImage.Bytes, myByteArray, 0, Convert.ToInt32(pngImage.Length)); MessagingCenter.Send<byte[]>(myByteArray, "ImageSelected"); } Device.BeginInvokeOnMainThread(() => { vc.DismissViewController(true, null); }); }; imagePicker.Canceled += (sender, e) => vc.DismissViewController(true, null); } catch (Exception e) { System.Diagnostics.Debug.WriteLine(e); } } … private void GotAccessToCamera(FileFormatEnum imageType, string imageId = null) { var imagePicker = new UIImagePickerController { SourceType = UIImagePickerControllerSourceType.Camera }; var window = UIApplication.SharedApplication.KeyWindow; var vc = window.RootViewController; while (vc.PresentedViewController != null) { vc = vc.PresentedViewController; } vc.PresentViewController(imagePicker, true, null); imagePicker.FinishedPickingMedia += (sender, e) => { UIImage image = (UIImage)e.Info.ObjectForKey(new NSString("UIImagePickerControllerOriginalImage")); UIImage rotateImage = RotateImage(image, image.Orientation); rotateImage = rotateImage.Scale(new CGSize(rotateImage.Size.Width, rotateImage.Size.Height), 0.5f); NSData imgData = null; if (imageType == FileFormatEnum.PNG) imgData = rotateImage.AsPNG(); else imgData = rotateImage.AsJPEG(); byte[] myByteArray = new byte[imgData.Length]; System.Runtime.InteropServices.Marshal.Copy(imgData.Bytes, myByteArray, 0, Convert.ToInt32(imgData.Length)); if (imageId != null) SavePhoto(rotateImage, imageId, imageType); MessagingCenter.Send<byte[]>(myByteArray, "ImageSelected"); Device.BeginInvokeOnMainThread(() => { vc.DismissViewController(true, null); }); }; imagePicker.Canceled += (sender, e) => vc.DismissViewController(true, null); } …
UWP:
public async void LaunchCamera(FileFormatEnum imageType, string imageId = null) { CameraCaptureUI captureUI = new CameraCaptureUI(); captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg; captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.JpegXR; captureUI.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Png; StorageFile photo = await captureUI.CaptureFileAsync(CameraCaptureUIMode.Photo); if (photo != null) { var stream = await photo.OpenAsync(FileAccessMode.Read); var reader = new DataReader(stream.GetInputStreamAt(0)); var bytes = new byte[stream.Size]; await reader.LoadAsync((uint)stream.Size); reader.ReadBytes(bytes); MessagingCenter.Send<byte[]>(bytes, "ImageSelected"); } } public async void LaunchGallery(FileFormatEnum imageType, string imageId = null) { FileOpenPicker openPicker = new FileOpenPicker(); openPicker.FileTypeFilter.Add(".jpg"); openPicker.FileTypeFilter.Add(".png"); openPicker.FileTypeFilter.Add(".jpeg"); StorageFile file = await openPicker.PickSingleFileAsync(); if (file != null) { var stream = await file.OpenAsync(FileAccessMode.Read); var reader = new DataReader(stream.GetInputStreamAt(0)); var bytes = new byte[stream.Size]; await reader.LoadAsync((uint)stream.Size); reader.ReadBytes(bytes); MessagingCenter.Send<byte[]>(bytes, "ImageSelected"); } }
Finally use the below code snippet to display the loaded image from galley or camera into SfImageEditor.
void OpenImageEditor(ImageSource imageSource) { editor.Source = imageSource; }
Output:
See also:
How do I add a shape to an image?
How do I add a text to an image?
How can I customize the default toolbar?