We use cookies to give you the best experience on our website. If you continue to browse, then you agree to our privacy policy and cookie policy. Image for the cookie policy date
Unfortunately, activation email could not send to your email. Please try again.
Syncfusion Feedback

How to load image from camera and gallery in Xamarin Image Editor (SfImageEditor)?

Platform: Xamarin.Forms |
Control: 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);
        }

 

Note:

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:

 

Xamarin.Forms SfImageEditor Demo to display the image from camera/gallery

 

Download the sample here.

 

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?

 

2X faster development

The ultimate Xamarin UI toolkit to boost your development speed.
ADD COMMENT
You must log in to leave a comment
Comments
John
Jan 22, 2020

System.NullReferenceException: 'Object reference not set to an instance of an object.'

Reply
Sheik Syed Abthaheer M [Syncfusion]
Jan 23, 2020

Hi John,

We have ensured this sample in all the platforms and its working properly. Can you share the replication steps, platform, and device info? It will be helpful for us to investigate further.

Keith
Feb 23, 2020

Hi I am trying this code but it looks out dated. Do you have newer code

Thank you

Reply
Bernard
Mar 23, 2020

Good afternoon,

I am running the above code on a Nokia 1 Model TA-1047, Android version 8.1.0 and when tappin on 'Take a photo' I get the following error at MainActivity.cs:81

Thanks for looking into this. Bernard

--- error --> {Android.OS.FileUriExposedException: file:///storage/emulated/0/Pictures/ImageEditor/ImageEditor_Photo_20200323173056867.jpg exposed beyond app through ClipData.Item.getUri() at Java.Interop.JniEnvironment+InstanceMethods.CallNonvirtualVoidMethod (Java.Interop.JniObjectReference instance, Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue args) [0x0008e] in <26521a5118b44c858c385715922b9d5d>:0 at Java.Interop.JniPeerMembers+JniInstanceMethods.InvokeVirtualVoidMethod (System.String encodedMember, Java.Interop.IJavaPeerable self, Java.Interop.JniArgumentValue parameters) [0x0005d] in <26521a5118b44c858c385715922b9d5d>:0 at Android.App.Activity.StartActivityForResult (Android.Content.Intent intent, System.Int32 requestCode) [0x00044] in <4ccdb3137d974856b786e1aeebbfbab6>:0 at IECameraandGallery.Droid.ImageEditorService.UploadFromCamera (IECameraandGallery.MainPage editor) [0x000d7] in C:\Git\Syncfusion\load-image-from-Camera-Gallery\IECameraandGallery\IECameraandGallery.Android\MainActivity.cs:81 at IECameraandGallery.MainPage.TakeAPhotoTapped (System.Object sender, System.EventArgs e) [0x0006f] in C:\Git\Syncfusion\load-image-from-Camera-Gallery\IECameraandGallery\IECameraandGallery\MainPage.xaml.cs:82 at Xamarin.Forms.TapGestureRecognizer.SendTapped (Xamarin.Forms.View sender) [0x0002e] in d:\agent\1\s\Xamarin.Forms.Core\TapGestureRecognizer.cs:48 at Xamarin.Forms.Platform.Android.TapGestureHandler.OnTap (System.Int32 count, Xamarin.Forms.Point point) [0x000a2] in d:\agent\1\s\Xamarin.Forms.Platform.Android\TapGestureHandler.cs:52 at Xamarin.Forms.Platform.Android.InnerGestureListener.Android.Views.GestureDetector.IOnGestureListener.OnSingleTapUp (Android.Views.MotionEvent e) [0x00014] in d:\agent\1\s\Xamarin.Forms.Platform.Android\InnerGestureListener.cs:151 at Android.Views.GestureDetector+IOnGestureListenerInvoker.n_OnSingleTapUp_Landroid_viewMotionEvent (System.IntPtr jnienv, System.IntPtr native__this, System.IntPtr native_e) [0x00011] in <4ccdb3137d974856b786e1aeebbfbab6>:0 at (wrapper dynamic-method) Android.Runtime.DynamicMethodNameCounter.43(intptr,intptr,intptr) --- End of managed Android.OS.FileUriExposedException stack trace --- android.os.FileUriExposedException: file:///storage/emulated/0/Pictures/ImageEditor/ImageEditor_Photo_20200323173056867.jpg exposed beyond app through ClipData.Item.getUri() at android.os.StrictMode.onFileUriExposed(StrictMode.java:1960) at android.net.Uri.checkFileUriExposed(Uri.java:2356) at android.content.ClipData.prepareToLeaveProcess(ClipData.java:942) at android.content.Intent.prepareToLeaveProcess(Intent.java:9850) at android.content.Intent.prepareToLeaveProcess(Intent.java:9835) at android.app.Instrumentation.execStartActivity(Instrumentation.java:1610) at android.app.Activity.startActivityForResult(Activity.java:4501) at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:767) at android.app.Activity.startActivityForResult(Activity.java:4459) at android.support.v4.app.FragmentActivity.startActivityForResult(FragmentActivity.java:754) at crc643f46942d9dd1fff9.InnerGestureListener.n_onSingleTapUp(Native Method) at crc643f46942d9dd1fff9.InnerGestureListener.onSingleTapUp(InnerGestureListener.java:79) at android.view.GestureDetector.onTouchEvent(GestureDetector.java:640) at crc64ee486da937c010f4.ImageRenderer.n_onTouchEvent(Native Method) at crc64ee486da937c010f4.ImageRenderer.onTouchEvent(ImageRenderer.java:62) at android.view.View.dispatchTouchEvent(View.java:11808) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at crc643f46942d9dd1fff9.Platform_DefaultRenderer.n_dispatchTouchEvent(Native Method) at crc643f46942d9dd1fff9.Platform_DefaultRenderer.dispatchTouchEvent(Platform_DefaultRenderer.java:55) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at crc643f46942d9dd1fff9.Platform_DefaultRenderer.n_dispatchTouchEvent(Native Method) at crc643f46942d9dd1fff9.Platform_DefaultRenderer.dispatchTouchEvent(Platform_DefaultRenderer.java:55) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at crc643f46942d9dd1fff9.Platform_DefaultRenderer.n_dispatchTouchEvent(Native Method) at crc643f46942d9dd1fff9.Platform_DefaultRenderer.dispatchTouchEvent(Platform_DefaultRenderer.java:55) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at crc643f46942d9dd1fff9.VisualElementRenderer_1.n_dispatchTouchEvent(Native Method) at crc643f46942d9dd1fff9.VisualElementRenderer_1.dispatchTouchEvent(VisualElementRenderer_1.java:65) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at crc643f46942d9dd1fff9.PlatformRenderer.n_dispatchTouchEvent(Native Method) at crc643f46942d9dd1fff9.PlatformRenderer.dispatchTouchEvent(PlatformRenderer.java:55) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at android.view.ViewGroup.dispatchTransformedTouchEvent(ViewGroup.java:3022) at android.view.ViewGroup.dispatchTouchEvent(ViewGroup.java:2680) at com.android.internal.policy.DecorView.superDispatchTouchEvent(DecorView.java:449) at com.android.internal.policy.PhoneWindow.superDispatchTouchEvent(PhoneWindow.java:1839) at android.app.Activity.dispatchTouchEvent(Activity.java:3321) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69) at android.support.v7.view.WindowCallbackWrapper.dispatchTouchEvent(WindowCallbackWrapper.java:69) at com.android.internal.policy.DecorView.dispatchTouchEvent(DecorView.java:411) at android.view.View.dispatchPointerEvent(View.java:12052) at android.view.ViewRootImpl$ViewPostImeInputStage.processPointerEvent(ViewRootImpl.java:4976) at android.view.ViewRootImpl$ViewPostImeInputStage.onProcess(ViewRootImpl.java:4786) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4318) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4371) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4337) at android.view.ViewRootImpl$AsyncInputStage.forward(ViewRootImpl.java:4464) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4345) at android.view.ViewRootImpl$AsyncInputStage.apply(ViewRootImpl.java:4521) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4318) at android.view.ViewRootImpl$InputStage.onDeliverToNext(ViewRootImpl.java:4371) at android.view.ViewRootImpl$InputStage.forward(ViewRootImpl.java:4337) at android.view.ViewRootImpl$InputStage.apply(ViewRootImpl.java:4345) at android.view.ViewRootImpl$InputStage.deliver(ViewRootImpl.java:4318) at android.view.ViewRootImpl.deliverInputEvent(ViewRootImpl.java:6912) at android.view.ViewRootImpl.doProcessInputEvents(ViewRootImpl.java:6886) at android.view.ViewRootImpl.enqueueInputEvent(ViewRootImpl.java:6843) at android.view.ViewRootImpl$WindowInputEventReceiver.onInputEvent(ViewRootImpl.java:7030) at android.view.InputEventReceiver.dispatchInputEvent(InputEventReceiver.java:186) at android.view.InputEventReceiver.nativeConsumeBatchedInputEvents(Native Method) at android.view.InputEventReceiver.consumeBatchedInputEvents(InputEventReceiver.java:177) at android.view.ViewRootImpl.doConsumeBatchedInput(ViewRootImpl.java:6997) at android.view.ViewRootImpl$ConsumeBatchedInputRunnable.run(ViewRootImpl.java:7053) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:916) at android.view.Choreographer.doCallbacks(Choreographer.java:728) at android.view.Choreographer.doFrame(Choreographer.java:654) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:902) at android.os.Handler.handleCallback(Handler.java:790) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:164) at android.app.ActivityThread.main(ActivityThread.java:6523) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:438) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:857) }

Reply
Bernard
Mar 24, 2020

Tested on a Huawei BG2-W09 tablet (Android 6.0 - API 23) and works well on that. Seems only the little Nokia phone has a problem with the camera (Gallery is fine).

Christoph
Jun 21, 2020

This code is very different from the linked github example, and it is incomplete! In the android example there are two uninitialized variables.

Could you please provide better documentation for this? I'm sure we're all able to extract the necessary information from the example somehow, but this incomplete / wrong example is bad :(

Reply
Sheik Syed Abthaheer M [Syncfusion]
Jun 23, 2020

Hi Christoph,

We modified and refreshed this document code as seen in the GitHub example.

Please sign in to access our KB

This page will automatically be redirected to the sign-in page in 10 seconds.

Up arrow icon

Warning Icon You are using an outdated version of Internet Explorer that may not display all features of this and other websites. Upgrade to Internet Explorer 8 or newer for a better experience.Close Icon

Live Chat Icon For mobile