question

Pafifi avatar image
0 Votes"
Pafifi asked ·

How to drag WritableBitmap between Image Controls?

Context:
Image1 is a Windows.UI.Xaml.Controls.Image
Image1.Source is WritableBitmap1, which is a Windows.UI.Xaml.Media.Imaging.WritableBitmap
Image2 is a Windows.UI.Xaml.Controls.Image
Now I want to drag Image1 to Image2, so that they show the same image. Now the code works like this:
When Image1.DragStarting:

 args.Data.SetBitmap(RandomAccessStreamReference.CreateFromStream(WritableBitmap1.PixelBuffer.AsStream.AsRandomAccessStream))

When Image2.Drop (e As DragEventArgs):

 Await (Await e.DataView.GetBitmapAsync()).OpenReadAsync'←Exception occurs here


The IRandomAccessStreamReference.OpenReadAsync() function fails:
System.NotSupportedException:“This IRandomAccessStream does not support the CloneStream method because it requires cloning and this stream does not support cloning.”

WritableImage1 is created programmatically and thus no files can be used as a source.

windows-uwp
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

FayWang-MSFT avatar image
0 Votes"
FayWang-MSFT answered ·

Hello,

Welcome to Microsoft Q&A!

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

This exception is because the parameter CreateFromStream method of RandomAccessStreamReference needs is Windows.Storage.Streams.IRandomAccessStream, but the type of WritableBitmap1.PixelBuffer.AsStream.AsRandomAccessStream is System.IO.IRandomAccessStream. So you need to convert the WritableBitmap to Windows.Storage.Streams.IRandomAccessStream. For example:


 IRandomAccessStream randomStream = new InMemoryRandomAccessStream();
 DataWriter dataWriter = new DataWriter(randomStream);
 dataWriter.WriteBuffer(WritableBitmap1.PixelBuffer, 0, WritableBitmap1.PixelBuffer.Length);
 await dataWriter.StoreAsync();
    
  args.Data.SetBitmap(RandomAccessStreamReference.CreateFromStream(randomStream));
· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

This nearly works. OpenReadAsync succeeded but the following ImageDecoding failed. However, your answer is inspiring enough for me to work out the final solution.

0 Votes 0 ·
jtorjo avatar image
0 Votes"
jtorjo answered ·

I haven't tested it, but I have played a bit with drag and drop.

You can, if you want, to do the drag-and-drop differently. Namely, put the bitmap in e.Data.Properties, like e.Data.Properties.Add("bitmap", your_bitmap)

On drop, you'll use e.DataView.Properties["bitmap"] as WriteableBitmap, and you should be fine.

As far as I know, you can have several image controls have the same source.

· 1 ·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

I've considered it, but I'm also planning another function to Copy the image into clipboard for other apps. So I need a universal format in DataPackage.

0 Votes 0 ·
Pafifi avatar image
0 Votes"
Pafifi answered ·

Here comes my final solution.

  1. Create a new InMemoryRandomAccessStream and a BitmapEncoder:

    Dim j As New InMemoryRandomAccessStream, d As BitmapEncoder = Await BitmapEncoder.CreateAsync(BitmapEncoder.PngEncoderId, j)

  2. Call SoftwareBitmap.CreateCopyFromBuffer to get a SoftwareBitmap from the PixelBuffer of the WritableBitmap, and set it to the BitmapEncoder.SetSoftwareBitmap, then FlushAsync.

  3. RandomAccessStreamReference.CreateFromStream(j) and pass it to the DataPackage.SetBitmap.

  4. Now the receiver gets the DataPackageView, GetBitmapAsync and then OpenReadAsync

  5. Create a BitmapDecoder by BitmapDecoder.CreateAsync, and GetSoftwareBitmapAsync.

I've tried that this even works for other apps that get the DataPackageView from Clipboard.

·
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.