Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin Forms Image to Stream

My goal is to take an embedded image which is saved in each project's image folder, stream it, convert it to a byte array and save it to the device's local storage file system using PCLStorage. The part which I cannot figure out is how to stream from the embedded image.

var embeddedImage = new Image { Aspect = Aspect.AspectFit };
embeddedImage.Source = ImageSource.FromResource("applicationIcon.png");

then I could stream it if I had the path, or I could convert it to a byte [] if I had a stream. The code below does not work because the file source is not found (obviously).

string localFileUri = string.Empty;

// Get hold of the file system.
IFolder localFolder = FileSystem.Current.LocalStorage;

IFile file = await FileSystem.Current.GetFileFromPathAsync("applicationIcon.png");

using (Stream stream = await file.OpenAsync(FileAccess.Read))
{
    using (var ms = new MemoryStream())
    {
        var byteArray = ms.ToArray();

        var storeragePath = await iStorageService.SaveBinaryObjectToStorageAsync(string.Format(FileNames.ApplicationIcon, app.ApplicationId), byteArray);
        app.IconURLLocal = storeragePath;
    }
}

The only option seems to be to use some kind of resource locator, and then maintain that code for each type of project you add. Not very elegant. Is there another way?

like image 976
Mark Garcia Avatar asked Feb 05 '23 07:02

Mark Garcia


2 Answers

First off, thank you to deckertron_9000 for putting me on the right path to figuring it out, and secondly these two links:

http://www.itgo.me/a/3956119637998661919/xamarin-forms-how-to-load-an-image-from-resources-into-a-byte-array

Xamarin Forms: How to use Embedded Resources in PCL Project for Image

In the end, this is what worked for me:

Firstly I added the image to a folder in my PCL. Then I made sure to change the image's Build Action to Embedded Resource.

Secondly, I added using System.Reflection;

Thirdly, this code worked for me:

string imagePath = "NameOfProject.Assets.applicationIcon.png";
Assembly assembly = typeof(NameOfClass).GetTypeInfo().Assembly;

byte[] buffer;
using (Stream stream = assembly.GetManifestResourceStream(imagePath))
{
    long length = stream.Length;
    buffer = new byte[length];
    stream.Read(buffer, 0, (int)length);

    var storeragePath = await iStorageService.SaveBinaryObjectToStorageAsync(string.Format(FileNames.ApplicationIcon, app.ApplicationId), buffer);
    app.IconURLLocal = storeragePath;
}
like image 125
Mark Garcia Avatar answered Feb 08 '23 16:02

Mark Garcia


 if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
        {
            await App.CurrentApp.MainPage.DisplayAlert("No Camera", ":( No camera available.", "OK");
            return;
        }

        _mediaFile = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
        {
            Directory = "Sample",
            Name = "test.jpg"
        });

        if (_mediaFile == null)
            return;

        //ViewModel.StoreImageUrl(file.Path);

        await App.CurrentApp.MainPage.DisplayAlert("Snap", "Your photo have been added to your Items collection.", "OK");

        ImageSource = ImageSource.FromStream(() =>
        {
            var stream = _mediaFile.GetStream();
            _mediaFile.Dispose();
            return stream;
        });
like image 35
Vimal Kotadia Avatar answered Feb 08 '23 15:02

Vimal Kotadia