简体   繁体   中英

Take or Select Multiple Image in Xamarin Forms

I am using "Plugin.Media.CrossPlatform" nuget for accessing Camera and take pictures in Xamarin Forms. But currently, it takes only a single picture at a time and upload only that last taken picture. I want to add multiple captures and allow a user to select a specific picture from recently captured images. How's that possible with this plugin in Android and IOS both Platform?

Also, I have added selection mode, If a user wants to select a picture from gallery. But there is the same issue. I want to select multiple images at a time and upload it, on both platforms. How's this implement in Xamarin Forms? Is there any example or blog for this task?

I am using this package.

The MediaPlugin doesn't allow multiple captures or picking up multiple pictures.

You have to implement platform methods and access them with Dependency Service, something like that. DependencyService.Get<IDoMultipleStuff>().TakePictures();

For Android you could take multiple pictures using INTENT_ACTION_STILL_IMAGE_CAMERA :

Intent intent = new Intent(
    MediaStore.INTENT_ACTION_STILL_IMAGE_CAMERA);
this.startActivity(intent);

While for iOS you can use PhotoPicker that can allow you to take multiple pictures before going back to your app.

In Android, you can select multiple images by putting in the Intent the extra ExtraAllowMultiple

var imageIntent = new Intent(Intent.ActionPick);
imageIntent.SetType ("image/*");
imageIntent.PutExtra (Intent.ExtraAllowMultiple, true);
imageIntent.SetAction (Intent.ActionGetContent);
((Activity)Forms.Context).StartActivityForResult(Intent.CreateChooser (imageIntent, "Select photo"), 0);

For iOS, you can use ELCImagePicker in this way.

var picker = ELCImagePickerViewController.Create();
picker.MaximumImagesCount = 15;

picker.Completion.ContinueWith (t => {
  if (t.IsCanceled || t.Exception != null) {
    // no pictures for you!
  } else {
     var items = t.Result as List<AssetResult>;
   }
});

PresentViewController (picker, true, null);

Xamarin Android forms take multiple pictures from Camera this is the solution for it.

public partial class App : Application
{
   // public static App Instance;

    public App ()
    {
        MainPage = new CameraGallery.MainPage();
        InitializeComponent();

    }
}

MainPage.xaml

// please install FlowListView and ffimageloading nuget pckg

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:CameraGallery"
             x:Class="CameraGallery.MainPage"
             xmlns:flv="clr-namespace:DLToolkit.Forms.Controls;assembly=DLToolkit.Forms.Controls.FlowListView"
             xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms"> 

            <StackLayout x:Name="CameraLayout">
                <flv:FlowListView FlowColumnCount="3" x:Name="listItemsCam" 
                        SeparatorVisibility="None"
                        HasUnevenRows="false" RowHeight="100" >
                    <flv:FlowListView.FlowColumnTemplate>
                        <DataTemplate >
                            <ffimageloading:CachedImage  DownsampleToViewSize="true" AbsoluteLayout.LayoutFlags="All" HeightRequest="100" AbsoluteLayout.LayoutBounds="0,0,1,1" Source="{Binding .}"  Aspect="AspectFill" HorizontalOptions="FillAndExpand">
                            </ffimageloading:CachedImage>
                        </DataTemplate>
                    </flv:FlowListView.FlowColumnTemplate>
                </flv:FlowListView>
                <!--<Image x:Name="image" IsVisible="False"></Image>-->
            </StackLayout>
</ContentPage>  

MainPage.xaml.cs

public partial class MainPage : ContentPage
    {
        ObservableCollection<string> camImageCollection;
        public static MainPage Instance;

        public MainPage()
        {
            InitializeComponent();
            Instance = this;

            var btn = new Button
            {
                Text = "Snap!",
                Command = new Command(o => ShouldTakePicture()),
            };
            CameraLayout.Children.Add(btn);  

            camImageCollection = new ObservableCollection<string>();
        }
        public event Action ShouldTakePicture = () => { };

        public void ShowImage(string[] filepath)
        {
           foreach(var item in filepath)
             camImageCollection.Add(item);
             listItemsCam.FlowItemsSource = camImageCollection;
        }
    }

now go to your android project inside it MainActivity.cs

[Activity(Label = "CameraGallery", Icon = "@drawable/icon", Theme = "@style/MainTheme", MainLauncher = true, ConfigurationChanges = ConfigChanges.ScreenSize | ConfigChanges.Orientation)]
public class MainActivity : global::Xamarin.Forms.Platform.Android.FormsAppCompatActivity
    {
        public static int OPENCAMERACODE = 102;
        //inside OnCreate after LoadApplication(new App()); add these lines
         protected override void OnCreate(Bundle bundle)
        {
            TabLayoutResource = Resource.Layout.Tabbar;
            ToolbarResource = Resource.Layout.Toolbar;
            UserDialogs.Init(this);
            base.OnCreate(bundle);

            global::Xamarin.Forms.Forms.Init(this, bundle);

            FlowListView.Init();
            CachedImageRenderer.Init(false);
            LoadApplication(new App());
            MainPage.Instance.ShouldTakePicture += () =>
            {
                ICursor cursor = loadCursor();
                image_count_before = cursor.Count;
                cursor.Close();
                Intent intent = new Intent(MediaStore.IntentActionStillImageCamera);
                IList<ResolveInfo> activities = PackageManager.QueryIntentActivities(intent, 0);
                if(activities.Count >0)
                    StartActivityForResult(Intent.CreateChooser(intent, "Camera Capture"), OPENCAMERACODE);
            };
        }
        public ICursor loadCursor()
        {
            string[] columns = new string[] { MediaStore.Images.ImageColumns.Data, MediaStore.Images.ImageColumns.Id };
            string orderBy = MediaStore.Images.ImageColumns.DateAdded;
            return ContentResolver.Query(MediaStore.Images.Media.ExternalContentUri, columns, null, null, orderBy);
        }
        private void exitingCamera()
        {
            ICursor cursor = loadCursor();
            string[] paths = getImagePaths(cursor, image_count_before);
            MainPage.Instance.ShowImage(paths);// this parameter pass to MainPage.xaml.cs
            cursor.Close();
        }
        public string[] getImagePaths(ICursor cursor, int startPosition)
        {
            int size = cursor.Count - startPosition;
            if (size <= 0) return null;
            string[] paths = new string[size];

            int dataColumnIndex = cursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data);
            for (int i = startPosition; i < cursor.Count; i++)
            {
                cursor.MoveToPosition(i);

                paths[i - startPosition] = cursor.GetString(dataColumnIndex);
            }
            return paths;
        }
        //inside OnActivityResult method do this
        protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
        {
            base.OnActivityResult(requestCode, resultCode, data);
            switch (requestCode)
            {
                case 102:
                        exitingCamera();
                    break;
            }
        }
    }   

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM