【问题标题】:Need help to deal with Photo for Xamarin forms需要帮助来处理 Photo for Xamarin 表单
【发布时间】:2017-05-12 10:03:09
【问题描述】:

我正在使用 xamarin 表单。我想为我的 iphone 应用程序从图库中挑选照片,并将其保存在 Azure DB 中。是否有任何可用于 xamarin 表单的解决方案。或者是否有任何插件可用于处理照片、文档或音频。任何帮助表示赞赏。

【问题讨论】:

标签: azure xamarin xamarin.ios xamarin.forms azure-mobile-services


【解决方案1】:

使用依赖服务,您可以从 Android / iPhone 拍摄或挑选照片:-

请参考下面的代码并尝试实现类似的代码:- 这是PCL中的接口:-

 public interface IGalleryProvider
    {
        Task<List<AttachmentMediaFile>> PickPhotoAsync();

        Task<List<AttachmentMediaFile>> PickAudioAsync();

        Task<List<AttachmentMediaFile>> PickDocumentAsync();

        Task<AttachmentMediaFile> PickProfilePhotoAsync();

        Task SaveToGalleryAsync(AttachmentMediaFile file);
    }

下面是代码,您只能使用它从 iPhone 中挑选或拍照:-

using AssetsLibrary;
using AVFoundation;
using ELCImagePicker;
using Foundation;
using MediaPlayer;
using MobileCoreServices;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using UIKit;


[assembly: Xamarin.Forms.Dependency(typeof(GalleryProvider))]

namespace SanketSample.MobileApp.Sample.iOS.Common
{
    public class GalleryProvider : IGalleryProvider
    {
        private TaskCompletionSource<List<AttachmentMediaFile>> _audioPickedTask;

        public async Task<List<AttachmentMediaFile>> PickAudioAsync()
        {
            _audioPickedTask = new TaskCompletionSource<List<AttachmentMediaFile>>();

            var picker = new MPMediaPickerController();

            ShowViewController(picker);

            picker.ItemsPicked += OnAudioPicked;
            picker.DidCancel += OnCancel;

            var media = await _audioPickedTask.Task;

            return media;
        }

        private void OnCancel(object sender, EventArgs e)
        {
            var picker = sender as MPMediaPickerController;
            picker.DidCancel -= OnCancel;
            picker.DismissViewController(true, null);

            _audioPickedTask.TrySetResult(new List<AttachmentMediaFile>());
        }

        private void OnAudioPicked(object sender, ItemsPickedEventArgs e)
        {
            var media = new List<AttachmentMediaFile>();

            var picker = sender as MPMediaPickerController;
            picker.ItemsPicked -= OnAudioPicked;
            picker.DismissViewController(true, null);

            if (e.MediaItemCollection.Items != null)
            {
                foreach (var item in e.MediaItemCollection.Items)
                {
                 //var vm1 = (new ViewModelLocator()).AttachmentsVM.SelectedAttachments.Add();

                    if (!item.IsCloudItem)
                    {
                        try
                        {
                            //var error = new NSError();
                            //var asset = new AVUrlAsset(item.AssetURL);
                            //var exporter = new AVAssetExportSession(asset, item.Title);
                            //exporter.OutputFileType = "com.apple.m4a-audio";
                            //AVAssetExportSession session = new AVAssetExportSession(asset, "");
                            //var reader = new AVAssetReader(asset, out error);
                            //var settings = new NSDictionary();
                            //Func<byte[]> bytesGetter = e.MediaItemCollection
                            //TODO item.Title, item.Title SSSanket,



                            //var _asset = AVAsset.FromUrl(NSUrl.FromFilename(item.AssetURL.ToString()));
                            //var _exportSession = new AVAssetExportSession(_asset, AVAssetExportSession.PresetPassthrough);
                            //_exportSession.OutputFileType = AVFileType.Aiff;






                           // media.Add(new AttachmentMediaFile(item.AssetURL.AbsoluteString, AttachmentMediaFileType.Audio, null , item.Title));



                        }
                        catch (Exception ex)
                        {
                            // throw ;
                        }

                    }
                }
            }

            _audioPickedTask.TrySetResult(media);
        }

        public async Task<List<AttachmentMediaFile>> PickDocumentAsync()
        {
            var task = new TaskCompletionSource<List<AttachmentMediaFile>>();

            var allowedUTIs = new string[]
                {
                    UTType.UTF8PlainText,
                    UTType.PlainText,
                    UTType.RTF,
                    UTType.Text,
                    UTType.PDF,
                    "com.microsoft.word.doc",
                    "com.microsoft.excel.xls"
                };

            var pickerMenu = new UIDocumentMenuViewController(allowedUTIs, UIDocumentPickerMode.Open);
            pickerMenu.DidPickDocumentPicker += (sender, args) =>
            {
                args.DocumentPicker.DidPickDocument += (sndr, pArgs) =>
                {
                    var securityEnabled = pArgs.Url.StartAccessingSecurityScopedResource();

                    NSError err;
                    var fileCoordinator = new NSFileCoordinator();
                    var docs = new List<AttachmentMediaFile>();

                    // Read bytes.
                    fileCoordinator.CoordinateRead(pArgs.Url, 0, out err, (NSUrl newUrl) =>
                    {
                        NSData data = NSData.FromUrl(newUrl);
                        docs.Add(new AttachmentMediaFile(pArgs.Url.AbsoluteString, AttachmentMediaFileType.Doc, data.ToArray(),null));
                        task.TrySetResult(docs);
                    });
                };

                ShowViewController(args.DocumentPicker);
            };

            ShowViewController(pickerMenu);

            return await task.Task;
        }

        public async Task<List<AttachmentMediaFile>> PickPhotoAsync()
        {
            var media = new List<AttachmentMediaFile>();
            var picker = ELCImagePickerViewController.Instance;
            picker.MaximumImagesCount = 15;

            ShowViewController(picker);

            await picker.Completion.ContinueWith(result =>
            {
                picker.BeginInvokeOnMainThread(() =>
                {
                    picker.DismissViewController(true, null);

                    if (!result.IsCanceled && result.Exception == null)
                    {
                        var imageEditor = new ImageEditor();
                        var items = result.Result as List<AssetResult>;
                        foreach (var item in items)
                        {

                                var bbytes= imageEditor.ResizeImage(item.Image, 1024, 1024);


                            media.Add(new AttachmentMediaFile(item.Path, AttachmentMediaFileType.Photo, bbytes, item.Name));
                        }
                    }
                });
            });

            return media;
        }

        public async Task<AttachmentMediaFile> PickProfilePhotoAsync()
        {
            AttachmentMediaFile selectMediaFile = null;
            var picker = ELCImagePickerViewController.Instance;
            picker.MaximumImagesCount = 1;
            ShowViewController(picker);

            await picker.Completion.ContinueWith(result =>
            {
                picker.BeginInvokeOnMainThread(() =>
                {
                    picker.DismissViewController(true, null);

                    if (!result.IsCanceled && result.Exception == null)
                    {
                        var imageEditor = new ImageEditor();
                        var items = result.Result as List<AssetResult>;
                        foreach (var item in items)
                        {
                            var bbytes = imageEditor.ResizeImage(item.Image, 1024, 1024);

                            selectMediaFile = new AttachmentMediaFile(item.Path, AttachmentMediaFileType.Photo, bbytes, item.Name);
                        }
                    }
                });
            });

            return selectMediaFile;
        }

        public async Task SaveToGalleryAsync(AttachmentMediaFile file)
        {
            var bytes = file.GetBytes();
            var originalImage = ImageEditor.ImageFromByteArray(bytes);

            var library = new ALAssetsLibrary();
            var orientation = (ALAssetOrientation)originalImage.Orientation;
            var nsUrl = await library.WriteImageToSavedPhotosAlbumAsync(originalImage.CGImage, orientation);
        }

        private void ShowViewController(UIViewController controller)
        {
            var topController = UIApplication.SharedApplication.KeyWindow.RootViewController;
            while (topController.PresentedViewController != null)
            {
                topController = topController.PresentedViewController;
            }

            topController.PresentViewController(controller, true, null);
        }
    }
}

以下是有用的类:-

 public class AttachmentMediaFile
{
    private readonly Func<byte[]> _bytesGetter;

    public string LocalPath { get; private set; }

    public string Name { get; private set; }

    public AttachmentMediaFileType Type { get; private set; }

    public AttachmentMediaFile(string localPath, AttachmentMediaFileType type, byte[] bytesGetter, string name = null)
    {
        LocalPath = localPath;
        Type = type;
        _bytesGetter = () =>
        {
            return bytesGetter;
        };

        if (string.IsNullOrEmpty(name))
        {
            Name = FileNameHelper.PrepareName(localPath);
        }
        else
        {
            Name = name;
        }
    }

    public byte[] GetBytes()
    {
        return _bytesGetter();
    }
}

public enum AttachmentMediaFileType
{
    Photo = 0,
    Audio = 1,
    Doc = 2,
    Video = 3, 
}

public static class FileNameHelper
{
    private const string Prefix = "IMG";

    public static string PrepareName(string localPath)
    {
        var name = string.Empty;

        if (!string.IsNullOrEmpty(localPath))
        {
            name = localPath.Split('/').Last();
        }

        return name;
    }

    public static string GenerateUniqueFileName(Extension extension)
    {
        var format = ".jpg";

        var fileName = string.Concat(Prefix, '_', DateTime.UtcNow.Ticks, format);

        return fileName;
    }

    public enum Extension
    {
        JPG
    }
}

现在,如果您想将数据存储到 Azure 服务器表,因此您已经在使用 Azure 移动服务客户端 SDK,同样您需要 Azure 中的 Blob nuget,您可以使用它通过将 blob 对象保存到 Azure 服务器来保存照片:-

使用管理 nuget 包安装 Microsoft.WindowsAzure.Storage.Auth 中的 blob 帮助程序 nuget; Microsoft.WindowsAzure.Storage.Blob; 这并尝试类似地实现我在下面给出的代码:-

using Acr.UserDialogs;
using Microsoft.WindowsAzure.Storage.Auth;
using Microsoft.WindowsAzure.Storage.Blob;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using SanketSample.MobileApp.sample.Business.Azure;
using SanketSample.MobileApp.sample.Business.Interfaces;
using SanketSample.MobileApp.sample.Models;
using SanketSample.MobileApp.sample.Models.AzureTables;
using SanketSample.MobileApp.sample.Models.Media;
using SanketSample.MobileApp.sample.Utils;
using Xamarin.Forms;

namespace SanketSample.MobileApp.Sanket.Common.Media
{
    public class BlobHelper
    {

        private const string ContainerName = "attachments";
        private Dictionary<string, TaskCompletionSource<bool>> _tasks;
        private IHttpService _httpservice { get; set; }

        #region Singleton Implementation

        private static readonly Lazy<BlobHelper> lazyInstance = new Lazy<BlobHelper>(() => new BlobHelper(), true);


        private BlobHelper()
        {
            _tasks = new Dictionary<string, TaskCompletionSource<bool>>();
        }

        public static BlobHelper Instance
        {
            get { return lazyInstance.Value; }`enter code here`
        }

        #endregion Singleton Implementation

        public async Task UploadAttachments(IList<AttachmentFile> attachments, long associatedRecordId, string category)
        {
            foreach (var attachment in attachments)
            {
                await UploadAttachment(attachment, associatedRecordId, category);
            }
        }

        public async Task UploadAttachment(AttachmentFile attachment, long associatedRecordId, string category)
        {
            try
            {
                CommonHelper commonHelper = new CommonHelper();
                attachment.ContainerName = ContainerName;
                attachment.AssociatedRecordId = associatedRecordId;
                //attachment.RecordId = commonHelper.GenerateRecordId();
                if (attachment.FileExtension == null)
                {
                    attachment.FileExtension = ConvertType(attachment.MediaFile);
                }

                attachment.Category = category;
                var taskCompletionSource = new TaskCompletionSource<bool>();

                if (!_tasks.ContainsKey(attachment.Name))
                { _tasks.Add(attachment.Name, taskCompletionSource); }
                else
                {
                    _tasks[attachment.Name] = taskCompletionSource;

                }

              //  _tasks.Add(attachment.Name, taskCompletionSource);
                var attachmentsTableOnline = AzureServiceProvider.Instance.GetRemoteTable<AttachmentFile>();
                if (CheckInternetConnection.IsConnected())
                {
                    await attachmentsTableOnline.InsertAsync(attachment);
                }
                var attachmentsTableOffline = AzureServiceProvider.Instance.GetLocalTable<AttachmentFile>();
                await attachmentsTableOffline.InsertAsync(attachment);

                if (!string.IsNullOrEmpty(attachment.SasQueryString))
                {
                    var credentials = new StorageCredentials(attachment.SasQueryString);
                    var imageUri = new Uri(attachment.Uri);

                    var container = new CloudBlobContainer(new Uri(string.Format("https://{0}/{1}",
                        imageUri.Host, attachment.ContainerName)), credentials);

                    var blobFromSASCredential = container.GetBlockBlobReference(attachment.Name);
                    try
                    {
                        var bytes = attachment.MediaFile.GetBytes();
                        await blobFromSASCredential.UploadFromByteArrayAsync(bytes, 0, bytes.Length);
                        if (CheckInternetConnection.IsConnected())
                        {
                            await attachmentsTableOnline.UpdateAsync(attachment);
                        }
                        await attachmentsTableOffline.UpdateAsync(attachment);
                        taskCompletionSource.TrySetResult(true);
                    }
                    catch (Microsoft.WindowsAzure.Storage.StorageException ex)
                    {
                        // Throws from UploadFromByteArrayAsync, but image uploaded.
                        System.Diagnostics.Debug.WriteLine($"BlobHelper: {ex}");
                        taskCompletionSource.TrySetResult(true);
                    }
                    catch (Exception ex)
                    {
                        System.Diagnostics.Debug.WriteLine($"BlobHelper: {ex}");
                        taskCompletionSource.TrySetResult(false);
                    }
                }
            }
            catch (Exception ca)
            {
                //throw ca;
            }
        }

        /// <summary>
        /// Downloads Blob Data boject and returns the Byts[] data
        /// </summary>
        /// <param name="file"></param>
        /// <returns></returns>
        public async Task<byte[]> DownloadAttachment(AttachmentFile file)
        {
            byte[] bytes = null;
            var fileContainer = file.Uri.Replace(file.Name, string.Empty);

            var container = new CloudBlobContainer(new Uri(fileContainer));
            var blob = container.GetBlockBlobReference(file.Name);
            using (var stream = new MemoryStream())
            {
                var isExist = await blob.ExistsAsync();
                if (isExist)
                {
                    await blob.DownloadToStreamAsync(stream);
                    bytes = stream.ToArray();
                }
            }

            return bytes;
        }


        /// <summary>
        /// Updates the Attachments Byts in the Azure Local Tables.
        /// </summary>
        /// <param name="AttachmentFileRecordId">Attachments Byte[] Data.</param>
        /// <returns></returns>

        public async Task<byte[]> DownloadAttachmentFileDetails(long? AttachmentFileRecordId, IHttpService service)
        {
            _httpservice = service;
            try
            {
                ResponseWrapper<AttachmentFileDetail> result = new ResponseWrapper<AttachmentFileDetail>();
                if (AttachmentFileRecordId != null)
                {

                    var request = Constants.API_BASE_URL + string.Format(Constants.API_ATTACHMENTS_PARAMETERS, AttachmentFileRecordId);
                    var response = await _httpservice.SendRequestAsync(HttpMethod.Get, request);
                    result.Status = response.Status;

                    if (response.IsSuccess)
                    {
                        result.Result = JsonConvert.DeserializeObject<AttachmentFileDetail>(response.Result);

                        if (result.Result == null)
                        {
                            result.Status = System.Net.HttpStatusCode.InternalServerError;
                        }
                        else
                        {
                            var output = result.Result;
                            var data = new List<AttachmentFileDetail>() { output };
                            await AzureServiceProvider.Instance.DatabaseService.InsertDataToLocalDB<AttachmentFileDetail>(data);
                            return result.Result.FileByteArray;
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ////throw ex;
            }
            finally
            {
            }

            return null;

        }

        private string ConvertType(AttachmentMediaFile file)
        {
            switch (file.Type)
            {
                case AttachmentMediaFileType.Doc:
                    return "doc";

                case AttachmentMediaFileType.Audio:
                    return "mp3";
            }

            return "jpeg";
        }
    }
}

【讨论】:

    【解决方案2】:

    github上的媒体插件

    对我来说效果很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-02-14
      • 2017-03-02
      • 1970-01-01
      • 1970-01-01
      • 2022-07-20
      • 2016-03-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多