Xamarin - 是不是有与适用于 Android 的 Photokit (iOS) 类似的框架,或者是获取图库中所有图像的文件流的好方法?

Posted

技术标签:

【中文标题】Xamarin - 是不是有与适用于 Android 的 Photokit (iOS) 类似的框架,或者是获取图库中所有图像的文件流的好方法?【英文标题】:Xamarin - Is there a similar framework to Photokit (iOS) available for Android, or a good way to get the filestream of all images in the gallery?Xamarin - 是否有与适用于 Android 的 Photokit (iOS) 类似的框架,或者是获取图库中所有图像的文件流的好方法? 【发布时间】:2019-09-02 13:19:18 【问题描述】:

我目前正在创建一个 Xamarin Forms 应用程序,我希望在其中检索设备库中的所有图像并将它们显示在网格中。我想使用带有本机实现的 DepdencyService 来做到这一点。

对于 ios,我使用 Photokit 框架来检索每个图像的 Stream 并将其输入到我的网格中。

我正在为 android 寻找一种类似的方法来解决这个问题。我试过浏览文档,但似乎找不到这样做的东西。

景色

 private void GetGallery()
        
            var imageStreams = DependencyService.Get<IGalleryFetcher>().GalleryStream();

            foreach (var stream in imageStreams)
             
               // Create image objects and set the stream as the image source
            

iOS 实现

 public ObservableCollection<Stream> GalleryStream()
        
            var streamArray = new ObservableCollection<Stream>();
            PHFetchResult fetchResult = PHAsset.FetchAssets(PHAssetMediaType.Image, null);
            for (int i = 0; i < fetchResult.Count(); i++)
            
                PHAsset phAsset = (PHAsset)fetchResult[i];
                string fileName = (NSString)phAsset.ValueForKey((NSString)"filename");

                PHImageManager.DefaultManager.RequestImageData(phAsset, null, (data, dataUti, orientation, info) =>
                
                    var path = (info?[(NSString)@"PHImageFileURLKey"] as NSUrl).FilePathUrl.Path;
                    Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
                    streamArray.Add(stream);

                );
            
            return streamArray;
        

Android 实现

//Help needed

是否有任何可用的框架或包可以帮助我在 Android 上做类似我在 iOS 上所做的事情?

编辑: 我使用 CrossMedia 插件来拍摄和选择图像,但我找不到该插件提供所需的功能。

我想要的功能是从图库中获取所有图像不需要主动操作或选择。没有文件选择器或导入操作,每个图像的(文件)流应该在视图打开时自动检索。

【问题讨论】:

检查github.com/jamesmontemagno/MediaPlugin。这是一个简单的跨平台插件,用于拍摄照片和视频或从共享代码的图库中挑选它们。 感谢@LucasZhang-MSFT 的回复,我应该提到我已经使用过这个插件,但是我找不到解决我想要做的事情的方法(自动检索设备库中每个图像的流并在视图中显示它们,无需任何交互或主动选择)。 ***.com/questions/57709184/… @LucasZhang-MSFT 我可能很难在这里看到解决方案,但据我所知,这仍然需要应用程序提示文件选择器,并且需要手动选择图像,对吗?我可能没有解释清楚。期望的结果是一个网格布局,无需采取任何主动操作即可导入您的画廊图像(例如发布帖子时的 Instagram 布局) Sflovik 你解释得很完美。就像人们不阅读问题,而只是发布指向其他内容的链接。我也在寻找一种从画廊加载所有照片的方法。也就是说,不是选择器。但找不到任何关于它的东西。 Everywhere 只是指向带有 photopickers 的相同 nuget 包的链接。你找到解决办法了吗? 【参考方案1】:

有兴趣的人的解决方案摘要。

根据@Lucas Zhanf - MSFT 的回答,这是最终解决方案。

Android - GalleryFetcherAndroid

   public ObservableCollection<string> GalleryStream()
        
            var gallerySources = new ObservableCollection<string>();
            Android.Net.Uri imageUri = MediaStore.Images.Media.ExternalContentUri;

            var cursor = Android.App.Application.Context.ContentResolver.Query(imageUri, null, MediaStore.Images.ImageColumns.MimeType + "=? or " + MediaStore.Images.ImageColumns.MimeType + "=?", new string[]  "image/jpeg", "image/png" , MediaStore.Images.ImageColumns.DateModified);

            while (cursor.MoveToNext())
            
                string path = cursor.GetString(cursor.GetColumnIndex(MediaStore.Images.ImageColumns.Data));
                gallerySources.Add(path);
            

            return gallerySources;
        

iOS - GalleryFetcheriOS

  public ObservableCollection<string> GalleryStream()
        
            var streamArray = new ObservableCollection<string>();
            PHFetchResult fetchResult = PHAsset.FetchAssets(PHAssetMediaType.Image, null);
            for (int i = 0; i < fetchResult.Count(); i++)
            
                PHAsset phAsset = (PHAsset)fetchResult[i];
                string fileName = (NSString)phAsset.ValueForKey((NSString)"filename");

                PHImageManager.DefaultManager.RequestImageData(phAsset, null, (data, dataUti, orientation, info) =>
                
                    var path = (info?[(NSString)@"PHImageFileURLKey"] as NSUrl).FilePathUrl.Path;
                    streamArray.Add(path);

                );
            
            return streamArray;
        

表单界面 - IGalleryFetcher

    public interface IGalleryFetcher
    
        ObservableCollection<string> GalleryStream();
    

示例用法 - ContentPage

  private void GetGallery()
        
            var imageSources = DependencyService.Get<IGalleryFetcher>().GalleryStream();
            foreach (var imageSource in imageSources)
            
                //Consider applying a limitation to the amount of images to load
                ImageSource source = ImageSource.FromFile(imageSource);
                //Use the image source for your view
            

【讨论】:

var path = (info?[(NSString)@"PHImageFileURLKey"] as NSUrl).FilePathUrl.Path;为我返回 null。有什么解决办法吗?使用 iPadOS 和 iOS 13.1 如果在 iOS 13 上检查我的答案:***.com/a/58332834/1700775【参考方案2】:

您可以在 Android 中使用 ContentResolver

Manifest.xml中添加以下权限

 <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
 <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />

在您的 DepdencyService 中

void GetAllImage()

   Android.Net.Uri imageUri = MediaStore.Images.Media.ExternalContentUri;
   var carsor = ContentResolver.Query(imageUri,null, MediaStore.Images.ImageColumns.MimeType + "=? or "+ MediaStore.Images.ImageColumns.MimeType+ "=?",new string[]  "image/jpeg", "image/png" , MediaStore.Images.ImageColumns.DateModified);

   while(carsor.MoveToNext())
   
     string path = carsor.GetString(carsor.GetColumnIndex(MediaStore.Images.ImageColumns.Data));
     Stream stream = new FileStream(path, FileMode.Open, FileAccess.Read);
     streamArray.Add(stream);
   


【讨论】:

这太完美了,非常感谢!在相关说明中,以防有人发现:考虑检索路径字符串,并根据需要从文件路径创建图像源。

以上是关于Xamarin - 是不是有与适用于 Android 的 Photokit (iOS) 类似的框架,或者是获取图库中所有图像的文件流的好方法?的主要内容,如果未能解决你的问题,请参考以下文章

适用于Xamarin Forms的Xamarin Firebase PhoneAuth

适用于 iOS 的 Xamarin 表单:启动画面显示蓝色边框

适用于 Xamarin 的 Genymotion Android 模拟器

Xamarin Forms AppShell 如何返回上一页

Ubuntu 18.04 上缺少适用于 Android 的文件 Xamarin

适用于 Android/iOS/WinPhone 的 Xamarin 通用层