Reputation: 1
I have an image tag on the view and the imagesource is binding into the imagesource variable in the viewmodel:
<Image Source="{Binding ImageSrc}"
Aspect="Fill"
x:Name="imgAvatar"
HeightRequest="300"
WidthRequest="300"/>
The initial imagesource variable when opening the view will be taken from resources/images . The user can then select a photo from the library or take a new photo, the imagesource variable will be changed accordingly.
private async void executeChangeImageCMD(string vl)
{
int sl = Convert.ToInt32(vl);
if (sl==0)
{
var mediaFile = await MediaPicker.PickPhotoAsync();
if (mediaFile != null)
{
var stream = await mediaFile.OpenReadAsync();
ImageSrc = ImageSource.FromStream(() => stream);
}
}
else
{
if (!MediaPicker.Default.IsCaptureSupported)
{
await Application.Current.MainPage.DisplayAlert("Oops!", "Error!", "OK");
return;
}
try
{
FileResult mediafile = await MediaPicker.Default.CapturePhotoAsync();
if (mediafile != null)
{
var stream = await mediafile.OpenReadAsync();
ImageSrc = ImageSource.FromStream(() => stream);
}
}
catch (Exception ex)
{
await Application.Current.MainPage.DisplayAlert("Oops!", "Error!", "OK");
}
}
}
Now when I need to convert this imagesource to bytearray to save data it fails. Can someone help me?
I tried with a transfer function like this:
public async Task<byte[]> ToByteArrayAsync(ImageSource imageSource)
{
try
{
if (imageSource is FileImageSource fileImageSource)
{
string imagePath = fileImageSource.File;
using (FileStream fs = new FileStream(imagePath, FileMode.Open, FileAccess.Read))
{
using (MemoryStream ms = new MemoryStream())
{
await fs.CopyToAsync(ms);
return ms.ToArray();
}
}
}
else if (imageSource is StreamImageSource streamImageSource)
{
Stream imageStream = await streamImageSource.Stream.Invoke(CancellationToken.None);
if (imageStream != null)
{
using (MemoryStream ms = new MemoryStream())
{
await imageStream.CopyToAsync(ms);
return ms.ToArray();
}
}
}
return null;
}
catch (Exception ex)
{
Console.WriteLine("Error: " + ex.Message);
return null;
}
}
I debug and see that the imagesource is still valid. However, when using FileStream, an error occurs with that path and an Exception is thrown and returns null.
Upvotes: 0
Views: 452
Reputation: 36629
You should be able to use the CopyBackBuffer method to get a BitmapSource, and then call the CopyPixels method. Something like
var bitmapSource = myImageSource.CopyBackBuffer();
var stride = bitmapSource.PixelWidth * 4;// assumes ABGR
var byteArray = new byte[stride * bitmapSource.PixelHeight];
bitmapSource.CopyPixels(byteArray, stride, 0);
Ideally you should get the stride from the bitmapSource itself to ensure everything is correct. But I cant find the proper way to do it from the documentation.
Upvotes: 0