Stream can't be accessed more than once.

Abraham John 111 Reputation points
2021-04-04T11:05:20.7+00:00

I'm using Ascetic.Plugins.Cropper inside my Xamarin project.

In MainViewModel page,

 public static byte[] imgbyte; 
 public MainViewModel(ICropper cropper)
    {
        CropCommand = new Command(async () =>
        {
            Stream cropped = await cropper.Crop();
            imgbyte = GetImageStreamAsBytes(cropped);
            ResultPhotoSource = ImageSource.FromStream(() => cropped);
        });
    }
   // Converting cropped image stream to bytes for later use
    public byte[] GetImageStreamAsBytes(Stream imgstream)
    {
        var buffer = new byte[16 * 1024];
        using (MemoryStream ms = new MemoryStream())
        {
            int read;
            while ((read = imgstream.Read(buffer, 0, buffer.Length)) > 0)
            {
                ms.Write(buffer, 0, read);
            }
            return ms.ToArray();
        }
    }

The
CropCommand
is binded to the
Command
property of a button.

So the image stream is succesfully converted into bytes but ResultPhotoSource is null.

In my crop.xaml page I've added an Image tag:

<Image x:Name="cropped_img" Source="{Binding ResultPhotoSource }"/>

But
cropped_img
displays nothing.

If I remove the line
imgbyte = GetImageStreamAsBytes(cropped);
, then ResultPhotoSource is binded to the
Source
of Image tag succesfully.

Why can't I access same stream more than once?

Help would be appreciated.

Xamarin
Xamarin
A Microsoft open-source app platform for building Android and iOS apps with .NET and C#.
5,292 questions
0 comments No comments
{count} votes

Accepted answer
  1. Cole Xia (Shanghai Wicresoft Co,.Ltd.) 6,751 Reputation points
    2021-04-05T06:09:33.183+00:00

    Hello,

    Welcome to Microsoft Q&A!

    We can't access a closed Stream , to avoid this we can create a new MemoryStream and copy the original data to it .

    Modify your code as below

       public MainViewModel(ICropper cropper)  
               {  
                   CropCommand = new Command(async () =>  
                   {  
                       Stream cropped = await cropper.Crop();  
                         
         
                       using (var ms = new MemoryStream())  
                       {  
         
                           cropped.CopyTo(ms);  
                           imgbyte = ms.ToArray();  
         
                           MemoryStream newM = new MemoryStream(imgbyte);  //add this line  
         
                           ResultPhotoSource = ImageSource.FromStream(() => newM);  
                       }  
         
                   });  
               }  
    

    If the response is helpful, please click "Accept Answer" and upvote it.
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

0 additional answers

Sort by: Most helpful