Home > Blockchain >  How to fetch images from gallery in CollectionView iOS 16 and Android 33 in NET MAUI?
How to fetch images from gallery in CollectionView iOS 16 and Android 33 in NET MAUI?

Time:11-16

I have a question regarding the possibility of fetching photos from the gallery for both iOS and Android and displaying them in a CollectionView. I dont want to use the FIle Picker or Media picker that gives the user the ability to select and pick the photos I want to load them directly. From what I have researched online targeting Android 30 makes it almost impossible to do so. I am not even sure how to even start when tackling this task, whenver I try to acces Environment.GetExternalDirectories I get a storage permission error stating I dont have access to it, but I have granted both read and write permissions in the manifest file and checked if they are granted. In terms of Ios I am not sure how to access the native paths to the gallery or in general how to tackle it. Any ideas would be really appreciated. Furthermore I would have to implement a gallery watcher to track when new images are added.

 var path = Android.OS.Environment.GetExternalStoragePublicDirectory(Android.OS.Environment.DirectoryPictures).AbsolutePath;
            try
            {
                string[] files = Directory.GetFiles(path);
                
                foreach (var file in files)
                {
                    try
                    {
                        var image = new Image
                        {
                            Source = ImageSource.FromFile(file)
                        };

                        var media = new MediaAsset
                        {
                            Path = file
                        };
                        MediaAssets.Add(media);
                    }
                    catch (Exception e)
                    {
                        // remove this if you don't want to see the exception message
                        continue;
                    }
                }
            }
            catch (Exception)
            {

                return;
            }

CodePudding user response:

you wrote a comment on one of my posts, it got deleted so i'll just answer you here :

I only did it on Android, but i guess it'll be similar for IOS, so i used the same Plateform specific code that you'll use in Xamarin.Forms

you get the path of the Image via [Android.App.Application.Context.ContentResolver.Query], then you load the image or thumbnail into a MemoryStream, wich you'll use to create an ImageSource that you return via an interface to your main code to display in an Image viewer

it worked, but i remember i had some problems with MAUI stability (don't remember what they were) that led me to just get back to Xamarin.Forms ..

This is what i used for the Picture/Thumbnail via the path :

    public async Task<MemoryStream> LoadThumbnail(string Path, int SizeX, int SizeY) {
        var mem = new MemoryStream();
        var bmp = Android.App.Application.Context.ContentResolver.LoadThumbnail(Android.Net.Uri.Parse(Path), new Android.Util.Size(SizeX, SizeY), null);
        bmp.Compress(Android.Graphics.Bitmap.CompressFormat.Jpeg, 100, mem); bmp.Recycle();
        mem.Seek(0, SeekOrigin.Begin);
        return mem;
    }

    public async Task<MemoryStream> LoadPicture(string Path) {
        var mem = new MemoryStream();
        Android.App.Application.Context.ContentResolver.OpenInputStream(Android.Net.Uri.Parse(Path)).CopyTo(mem);
        mem.Seek(0, SeekOrigin.Begin);
        return mem;
    }

then you use something like this : ImageSource.FromStream(() => Stream); to get the imageSource

PS : (just to help you in future problems, when you use an ImageSource from stream, each time you load it the stream get's closed, and that's why it uses a lambda instead of a direct value, it's so that you can reload the stream)

Edit : so this is how you get gallery paths :

var uriExternal = MediaStore.Images.Media.ExternalContentUri; //Since Android 12

string[] projection = { (MediaStore.Images.Media.InterfaceConsts.Id), (MediaStore.Images.Media.InterfaceConsts.DateAdded), (MediaStore.Images.Media.InterfaceConsts.RelativePath) };
var cursor = Android.App.Application.Context.ContentResolver.Query(uriExternal, projection, null, null, MediaStore.Images.Media.InterfaceConsts.DateAdded);


if (cursor != null) {
    int columnIndexID = cursor.GetColumnIndexOrThrow(MediaStore.Images.Media.InterfaceConsts.Id);
    int RelativePathID = cursor.GetColumnIndexOrThrow(MediaStore.Images.Media.InterfaceConsts.RelativePath);
    
    
    while (cursor.MoveToNext()) {

        //This is the image path on the Device
        string RelativePath = cursor.GetString(RelativePathID); 
        
        //This is the path you'll use to load the Image
        string ExternalSrcPath = uriExternal   "/"   cursor.GetLong(columnIndexID); 
        
        ...

    }
}
  • Related