Search code examples
c#streamuwpclonerandom-access

C# UWP Converting from System.IO.Stream to Windows.Storage.Streams.IRandomAccessStreamWithContentType


so I am trying to get IRandomAccessStreamWithContentType but cant, because I get exception:

"This IRandomAccessStream does not support the CloneStream method because it requires cloning and this stream does not support cloning."

And this happens on last line of the following code:

PixelDataProvider pix = await decoder.GetPixelDataAsync(
                BitmapPixelFormat.Bgra8,
                BitmapAlphaMode.Straight,
                transform,
                ExifOrientationMode.IgnoreExifOrientation,
                ColorManagementMode.ColorManageToSRgb);
byte[] pixels = pix.DetachPixelData();

Stream pixStream = cropBmp.PixelBuffer.AsStream();
pixStream.Write(pixels, 0, (int)(width * height * 4));
IRandomAccessStream iStream= pixStream.AsRandomAccessStream(); //dafaq with streams
RandomAccessStreamReference iReferenceStream= RandomAccessStreamReference.CreateFromStream(iStream);
IRandomAccessStreamWithContentType newStream = await iReferenceStream.OpenReadAsync();

Is there any workaround or something?

Edit 1

I have also tried this way, still doesn't work. (But now I get null not that Clone failed)

InMemoryRandomAccessStream ras = new InMemoryRandomAccessStream();
await ras.WriteAsync(pixels.AsBuffer());
RandomAccessStreamReference iReferenceStream = RandomAccessStreamReference.CreateFromStream(ras);
IRandomAccessStreamWithContentType newStream = await iReferenceStream.OpenReadAsync();

Solution

  • From your code, it seems you have used BitmapDecoder. The BitmapDecoder provides read access to bitmap container data as well as data from the first frame.

    We should be able to create a new InMemoryRandomAccessStream for the encoder to write to and call BitmapEncoder.CreateForTranscodingAsync, passing in the in-memory stream and the decoder object.

    For example:

    Windows.Storage.Streams.IRandomAccessStream random = await Windows.Storage.Streams.RandomAccessStreamReference.CreateFromUri(new Uri("ms-appx:///Assets/sunset.jpg")).OpenReadAsync();
    Windows.Graphics.Imaging.BitmapDecoder decoder = await Windows.Graphics.Imaging.BitmapDecoder.CreateAsync(random);
    Windows.Graphics.Imaging.PixelDataProvider pixelData = await decoder.GetPixelDataAsync();
    byte[] buffer = pixelData.DetachPixelData();
    InMemoryRandomAccessStream inMemoryRandomAccessStream = new InMemoryRandomAccessStream();
    BitmapEncoder encoder = await BitmapEncoder.CreateForTranscodingAsync(inMemoryRandomAccessStream, decoder);
    encoder.BitmapTransform.ScaledWidth = 320;
    encoder.BitmapTransform.ScaledHeight = 240;
    await encoder.FlushAsync();
    inMemoryRandomAccessStream.Seek(0);
    random.Seek(0);
    BitmapImage bitmapImage = new BitmapImage();
    RandomAccessStreamReference iReferenceStream = RandomAccessStreamReference.CreateFromStream(inMemoryRandomAccessStream);
    IRandomAccessStreamWithContentType newStream = await iReferenceStream.OpenReadAsync();
    bitmapImage.SetSource(newStream);
    MyImage.Source = bitmapImage;