Xamarin Android Gallary Photo Stream имеет нулевую базу - PullRequest
0 голосов
/ 29 октября 2018

Я пытаюсь получить изображение из галереи, а затем получить байты из этого изображения. Эта концепция работает для PDF и видео, хотя с изображениями поток, который я получаю BaseInputStream, равен нулю, и поэтому при попытке копирования в поток памяти (я считаю) я пробовал разные намерения и устанавливал позицию в 0 перед копированием, но без преобладания , Весь связанный код приведен ниже.

Создание намерения

    public const int GalleryPhoto = 4;
    public const int GalleryVideo = 5;
    public const int SelectFile = 7;

void IDevice.GetImageFromGallery()
    {
        if (_dir == null)
        { CreateDirectoryForPictures(); }
        Intent imageIntent = new Intent();
        imageIntent.SetType("image/*");
        imageIntent.SetAction(Intent.ActionGetContent);
        MyApp.Droid.MainActivity.Main.StartActivityForResult(imageIntent, GalleryPhoto);
    }

    void IDevice.SelectFile()
    {
        if (_dir == null)
        { CreateDirectoryForPictures(); }
        Intent imageIntent = new Intent();
        imageIntent.SetType("application/pdf");
        imageIntent.SetAction(Intent.ActionOpenDocument);
        MyApp.Droid.MainActivity.Main.StartActivityForResult(imageIntent, SelectFile);
    }

    void IDevice.GetVideoFromGallery()
    {
        if (_dir == null)
        { CreateDirectoryForPictures(); }
        Intent imageIntent = new Intent();
        imageIntent.SetType("video/*");
        imageIntent.SetAction(Intent.ActionGetContent);
        MyApp.Droid.MainActivity.Main.StartActivityForResult(imageIntent, GalleryVideo);
    }

OnActivityResult в MainActivity.cs

  protected override void OnActivityResult(int requestCode, Result resultCode, Intent data)
    {
        base.OnActivityResult(requestCode, resultCode, data);
        {
            if (resultCode == Result.Ok)
            {

                if (requestCode == AndroidDevice.GalleryPhoto)
                {
                    selectedFile = data.Data;
                    System.IO.Stream stream = ContentResolver.OpenInputStream(data.Data);
                    AndroidDevice._stream = stream;
                    AndroidDevice.ImageHasBeenTaken();
                }
                else if (requestCode == AndroidDevice.GalleryVideo)
                {
                    selectedFile = data.Data;
                    System.IO.Stream stream = ContentResolver.OpenInputStream(data.Data);
                    AndroidDevice._stream = stream;
                    AndroidDevice.VideoHasBeenTaken();
                }
                else if (requestCode == AndroidDevice.SelectFile)
                {
                    selectedFile = data.Data;
                    System.IO.Stream stream = ContentResolver.OpenInputStream(data.Data);
                    AndroidDevice._stream = stream;
                    AndroidDevice.FileHasBeenSelected();

                }
            }
            GC.Collect();
        }
    }

Я сохраняю поток с объектом и использую его для отображения изображения, если оно выбрано, и затем использую его для загрузки байтов.

Отображение изображения отлично работает из потока

this.ImageObj.Source = ImageSource.FromStream(()=>stream);

У меня есть хороший и простой метод получения байтов из потока

public byte[] GetBytes()
    {
        byte[] bytes = new byte[0];
        try
        {                
            if (stream!= null)
            {
                MemoryStream ms  = new MemoryStream();
                stream.CopyTo(ms);
                bytes = ms.ToArray();                  
            }
            return bytes;
        }
        catch(Exception ex)
        {
            Screens.DisplayExcpetion de = new Screens.DisplayExcpetion(ex);
            return bytes;
        }
    }

Это работает для PDF-файлов и видео, хотя при выборе изображения появляется следующая ошибка

{System.NullReferenceException: ссылка на объект не установлена ​​в экземпляр объекта. на Android.Runtime.InputStreamInvoker.Read (Буфер System.Byte [], смещение System.Int32, счет System.Int32) [0x00006] в: 0 в System.IO.Stream.InternalCopyTo (назначение System.IO.Stream, System.Int32 bufferSize) [0x00015] в <05f5f767747c4c30800c25866dc4cdd4>: 0 в System.IO.Stream.CopyTo (Пункт назначения System.IO.Stream) [0x00099] в <05f5f767747c4c30800c25866dc4cdd4>: 0 at (оболочка remoting-invoke-with-check) System.IO.Stream:CopyTo (System.IO.Stream) в DAFCheckMobile_DEV.Controls.CTLUploadImage.GetBytes () [0x0001d] в E: \ Data \ Решения \ DAF \ DAFcheckMobile \ DAFcheckMobile_DEV \ DAFCheckMobile_DEV \ DAFCheckMobile_DEV \ Controls \ CTLUploadImage.cs: 325 }

Единственное, что я заметил в отличающемся потоке, это то, что stream.BaseInputStream имеет значение null.

Я искал ответ на этот вопрос, хотя есть похожие вопросы, я не могу найти никого с такой же проблемой или решением, которое работает.

Я отлаживаю это на Samsung SM-G920F (Android 7.0 - API 24)

Любая помощь будет принята с благодарностью, я некоторое время стучал головой об стену, извините, если пост слишком затянут.

1 Ответ

0 голосов
/ 29 октября 2018

Использование потока для получения источника изображения, по-видимому, и стало причиной того, что BaseInputStream стал нулевым, сначала получая байты, а затем источник изображения из этих байтов.

...