android 如何在Xamarin表单中从图库中选择多个图像并保存到所需的文件路径?

vi4fp9gy  于 2022-12-31  发布在  Android
关注(0)|答案(3)|浏览(144)

我有下面的代码来打开画廊。

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

我坚持使用以下代码,这是我的MainActivity.cs中的OnActivityResult

protected override void OnActivityResult(int requestCode, Android.App.Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);

        if((requestCode==1)&&(resultCode==Result.Ok))
        {
            if(data!=null)
            {
                ClipData clipData = data.ClipData;
                if(clipData!=null)
                {
                    for (int i = 0; i < clipData.ItemCount; i++)
                    {
                        ClipData.Item item = clipData.GetItemAt(i);
                        Android.Net.Uri selectedImage = item.Uri;

                        //How to convert Android.Net.Uri to a image file?

                    }
                }
            }
        }
    }

android .NET.Uri是我从来没有见过的东西,路径就像content/android/document/documents/31857.是的,我可以从图库中选择多张照片,但我就是不知道如何将Android.Net.URI转换为法律的的图像文件?我的最终目标是将所选图像保存到我想要的文件路径,如storage/emulated/0...或者有没有更好的方法来选择多个图像并保存到所需的文件?谢谢。

vojdkbi0

vojdkbi01#

您可以使用依赖关系服务

在表单中创建界面

namespace xxx
{
    public interface IPhotoPickerService
    {
        Task<Dictionary<string,Stream>> GetImageStreamAsync();
    }
}

在iOS中

[assembly: Dependency (typeof (PhotoPickerService))]
namespace xxx.iOS
{
    public class PhotoPickerService : IPhotoPickerService
    {
        TaskCompletionSource<Dictionary<string, Stream>> taskCompletionSource;
        UIImagePickerController imagePicker;

        Task<Dictionary<string, Stream>> IPhotoPickerService.GetImageStreamAsync()
        {
            // Create and define UIImagePickerController
            imagePicker = new UIImagePickerController
            {
                SourceType = UIImagePickerControllerSourceType.PhotoLibrary,
                MediaTypes = UIImagePickerController.AvailableMediaTypes(UIImagePickerControllerSourceType.PhotoLibrary)
            };

            // Set event handlers
            imagePicker.FinishedPickingMedia += OnImagePickerFinishedPickingMedia;
            imagePicker.Canceled += OnImagePickerCancelled;

            // Present UIImagePickerController;
            UIWindow window = UIApplication.SharedApplication.KeyWindow;
            var viewController = window.RootViewController;
            viewController.PresentModalViewController(imagePicker, true);

            // Return Task object
            taskCompletionSource = new TaskCompletionSource<Dictionary<string, Stream>>();
            return taskCompletionSource.Task;
        }

       

        void OnImagePickerFinishedPickingMedia(object sender, UIImagePickerMediaPickedEventArgs args)
        {
            UIImage image = args.EditedImage ?? args.OriginalImage;

            if (image != null)
            {
                // Convert UIImage to .NET Stream object
                NSData data;
                if (args.ReferenceUrl.PathExtension.Equals("PNG") || args.ReferenceUrl.PathExtension.Equals("png"))
                {
                    data = image.AsPNG();
                }
                else
                {
                    data = image.AsJPEG(1);
                }
                Stream stream = data.AsStream();

                UnregisterEventHandlers();

                Dictionary<string, Stream> dic = new Dictionary<string, Stream>();
                dic.Add(args.ImageUrl.ToString(), stream);

                // Set the Stream as the completion of the Task
                taskCompletionSource.SetResult(dic);
            }
            else
            {
                UnregisterEventHandlers();
                taskCompletionSource.SetResult(null);
            }
            imagePicker.DismissModalViewController(true);
        }

        void OnImagePickerCancelled(object sender, EventArgs args)
        {
            UnregisterEventHandlers();
            taskCompletionSource.SetResult(null);
            imagePicker.DismissModalViewController(true);
        }

        void UnregisterEventHandlers()
        {
            imagePicker.FinishedPickingMedia -= OnImagePickerFinishedPickingMedia;
            imagePicker.Canceled -= OnImagePickerCancelled;
        }

        
    }
}

在安卓系统中

    • 在主要活动中**

一个二个一个一个

调用它

Dictionary<string, Stream> dic = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();

Stream stream;
string path;

foreach ( KeyValuePair<string, Stream> currentImage in dic )
{
   stream = currentImage.Value;

   // save it    

}
epggiuax

epggiuax2#

谢谢你的帮助。2下面是我给那些需要帮助的人的最终解决方案。

private string GetPathToImage(Android.Net.Uri uri)
    {
        string doc_id = "";
        using (var c1 = ContentResolver.Query(uri, null, null, null, null))
        {
            c1.MoveToFirst();
            string document_id = c1.GetString(0);
            doc_id = document_id.Substring(document_id.LastIndexOf(":") + 1);
        }

        string path = null;

        // The projection contains the columns we want to return in our query.
        string selection = Android.Provider.MediaStore.Images.Media.InterfaceConsts.Id + " =? ";
        using (var cursor = ContentResolver.Query(Android.Provider.MediaStore.Images.Media.ExternalContentUri, null, selection, new string[] { doc_id }, null))
        {
            if (cursor == null) return path;
            var columnIndex = cursor.GetColumnIndexOrThrow(Android.Provider.MediaStore.Images.Media.InterfaceConsts.Data);
            cursor.MoveToFirst();
            path = cursor.GetString(columnIndex);
        }
        return path;
    }

之后,你可以做任何你想做的,干杯!取自:获取画廊图像Xamarin的路径?

4dbbbstv

4dbbbstv3#

这是在Xamarin中从Gallery中挑选多张照片的iOS实现。调用Task〈List〈byte[]〉〉PickPhotos()后,你会得到一个字节数组列表。Android实现在Montemagno的跨媒体插件中运行良好,但iOS有缺陷。这应该可以修复它。我正在使用新的PHPickerViewController来完成这件事。还包括一个本Map像大小调整例程,如果需要的话,可以缩小照片的大小。

public class PhotoService 
{
    public override async Task<List<byte[]>> PickPhotos()
    {
        var imagePicker = new PHPickerViewController(new PHPickerConfiguration
        {
            Filter = PHPickerFilter.ImagesFilter,
            SelectionLimit = 50,
        });
        var window = UIApplication.SharedApplication.KeyWindow;
        var vc = window.RootViewController;
        while (vc.PresentedViewController != null)
        {
            vc = vc.PresentedViewController;
        }
        var tcs = new TaskCompletionSource<Task<List<byte[]>>>();

        imagePicker.Delegate = new PPD
        {
            CompletedHandler = res => tcs.TrySetResult(PickerResultsToMediaFile(res))
        };
        await vc.PresentViewControllerAsync(imagePicker, true);
        var resultTask = await tcs.Task;
        var result = await resultTask;
        await vc.DismissViewControllerAsync(true);
        imagePicker?.Dispose();
        return result;
    }

    private async Task<List<byte[]>> PickerResultsToMediaFile(PHPickerResult[] res)
    {
        var results = new List<byte[]>();
        var tcs = new TaskCompletionSource<NSObject>();
        foreach (var item in res)
        {
            try
            {
                var provider = item.ItemProvider;
                var suggestedName = provider.SuggestedName;
                var identifiers = provider?.RegisteredTypeIdentifiers;

                var identifier = (identifiers?.Any(i => i.StartsWith(UTType.LivePhoto)) ?? false)
                    && (identifiers?.Contains(UTType.JPEG) ?? false)
                    ? identifiers?.FirstOrDefault(i => i == UTType.JPEG)
                    : identifiers?.FirstOrDefault();
                if (string.IsNullOrWhiteSpace(identifier))
                    continue;
                var fileName = $"{provider?.SuggestedName}.{GetTag(identifier, UTType.TagClassFilenameExtension)}";
                var stream = (await provider.LoadDataRepresentationAsync(identifier))?.AsStream();
                byte[] bytes;
                using (MemoryStream ms = new MemoryStream())
                {
                    stream.CopyTo(ms);
                    bytes = ms.ToArray();
                }
                results.Add(bytes);
            }
            catch(Exception)
            {
                continue;
            }
        }
        return results;
    }
public override byte[] ResizeImage(byte[] imageData)
    {
        float width, height;
        UIImage originalImage = ImageFromByteArray(imageData);
        if (originalImage == null)
        {
            return imageData;
        }
        UIImageOrientation orientation = originalImage.Orientation;

        if (originalImage.Size.Width > originalImage.Size.Height)
        {
            if (originalImage.Size.Width > 1920)
            {
                width = 1920;
                height = 1920 * (float)originalImage.Size.Height / (float)originalImage.Size.Width;
            }
            else
            {
                width = (float)originalImage.Size.Width;
                height = (float)originalImage.Size.Height;
            }
        }
        else
        {
            if (originalImage.Size.Height > 1920)
            {
                height = 1920;
                width = 1920 * (float)originalImage.Size.Width / (float)originalImage.Size.Height;
            }
            else
            {
                width = (float)originalImage.Size.Width;
                height = (float)originalImage.Size.Height;
            }
        }

        //create a 24bit RGB image
        using (CGBitmapContext context = new CGBitmapContext(IntPtr.Zero,
                                             (int)width, (int)height, 8,
                                             4 * (int)width, CGColorSpace.CreateDeviceRGB(),
                                             CGImageAlphaInfo.PremultipliedFirst))
        {

            RectangleF imageRect = new RectangleF(0, 0, width, height);

            // draw the image
            context.DrawImage(imageRect, originalImage.CGImage);

            UIImage resizedImage = UIImage.FromImage(context.ToImage(), 0, orientation);

            // save the image as a jpeg
            return resizedImage.AsJPEG().ToArray();
        }
    }
    public UIImage ImageFromByteArray(byte[] data)
    {
        if (data == null)
        {
            return null;
        }

        UIImage image;
        try
        {
            image = new UIImage(Foundation.NSData.FromArray(data));
        }
        catch (Exception e)
        {
            Console.WriteLine("Image load failed: " + e.Message);
            return null;
        }
        return image;
    }
    protected internal static string GetTag(string identifier, string tagClass)
        => UTType.CopyAllTags(identifier, tagClass)?.FirstOrDefault();
}
class PPD : PHPickerViewControllerDelegate
{
    public Action<PHPickerResult[]> CompletedHandler { get; set; }

    public override void DidFinishPicking(PHPickerViewController picker, PHPickerResult[] results) =>
        CompletedHandler?.Invoke(results?.Length > 0 ? results : null);
}

相关问题