4

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?

4
  • It sounds like you're looking for embedded resources. You would then access the stream via Assembly.GetManifestResourceStream method. Commented Jan 18, 2017 at 16:49
  • You would also have to make sure the build action on the image is embedded resource. Commented Jan 18, 2017 at 16:53
  • Thank you deckertron_9000. That put me on the right path to figuring it out! Commented Jan 18, 2017 at 20:11
  • If you have time you should write up an answer to your question on here so other people can learn as well :) Commented Jan 18, 2017 at 20:16

2 Answers 2

7

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; } 
Sign up to request clarification or add additional context in comments.

1 Comment

What do you mean of 'NameOfClass' in your second line of code?
2
 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; }); 

1 Comment

Thank you Vimal. Using the CrossMedia plugin works if you have a path. In my case I didn't have a path and had to use the Assembly class.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.