In WinRT, how do I upload an image and then wait only until it is necessary to upload it before writing to it?

I am using WriteableBitmapEx in a WinRT project. I am loading an image in WriteableBitmap from a user image library. However, I cannot immediately write this image, if I do, it will be overwritten by the image itself (it looks like Async loads the image, and then on top of its image on top of it). I don't know how to stop him from doing this (I tried using Await in SetSource, but not Async method).

I used "Await Task.Delay (1000)" and it works, but it seems to be hacked because 1000 ms may or may not be enough. I would like it to wait for the bitmap to load before continuing.

Could someone seem on top of what I'm doing wrong, or suggest how can I guarantee that WriteableBitmap is loaded from the image library before doing any processing? Here is an example of a piece of code that I created:

Dim file = Await picker.PickSingleFileAsync

If file Is Nothing Then
    Exit Sub
End If

Dim wbm As New WriteableBitmap(1, 1)
wbm.SetSource(Await file.OpenAsync(Windows.Storage.FileAccessMode.Read))

' If I don't have this, the DrawLine will not show up, if I do, it will.
Await Task.Delay(1000)

wbm.DrawLine(1, 1, 255, 255, Colors.Green)
wbm.Invalidate()

ImageMain.Source = wbm
+2
source share
3 answers

Returning OpenAsync means that the stream is available, and not that the data is actually read from it. It looks like you would like to open + read first, and then everything will be fine.

, ReadAsync , , DataReader OpenReadAsync, IRandomAccessStream.

var randomAccessStream = await file.OpenReadAsync();

var dataReader = new DataReader(randomAccessStream);
await dataReader.LoadAsync(randomAccessStream.Size);

byte[] imageBytes;
dataReader.ReadBytes(out imageBytes);

wbm.SetSource(new MemoryStream(imageBytes));
+2

, WriteableBitmap. WriteableBitmapEx:

/// <summary>
/// Loads an image from the applications content and fills this WriteableBitmap with it.
/// </summary>
/// <param name="bmp">The WriteableBitmap.</param>
/// <param name="uri">The URI to the content file.</param>
/// <returns>The WriteableBitmap that was passed as parameter.</returns>
public static async Task<WriteableBitmap> FromContent(this WriteableBitmap bmp, Uri uri)
{
   // Decode pixel data
   var file = await StorageFile.GetFileFromApplicationUriAsync(uri);
   var decoder = await BitmapDecoder.CreateAsync(await file.OpenAsync(FileAccessMode.Read));
   var transform = new global::Windows.Graphics.Imaging.BitmapTransform();
   var pixelData = await decoder.GetPixelDataAsync(decoder.BitmapPixelFormat, decoder.BitmapAlphaMode, transform, ExifOrientationMode.RespectExifOrientation, ColorManagementMode.ColorManageToSRgb);
   var pixels = pixelData.DetachPixelData();

   // Copy to WriteableBitmap
   bmp = new WriteableBitmap((int)decoder.PixelWidth, (int)decoder.PixelHeight);
   using (var bmpStream = bmp.PixelBuffer.AsStream())
   {
      bmpStream.Seek(0, SeekOrigin.Begin);
      bmpStream.Write(pixels, 0, (int)bmpStream.Length);
      return bmp;
   }
}

BTW, WinRT WriteableBitmapEx.;) http://kodierer.blogspot.de/2012/05/one-bitmap-to-rule-them-all.html

+8

I do not think that WB has events that BitmapImage does to wait for it to open. I would try using BitmapDecoder / CreateAsync / GetPixelDataAsync / DetachPixelData and copy the resulting byte array to the WB pixel buffer instead of calling wb.SetSource (). Then maybe call wb.Invalidate (). Or just replace the Delay call with Invalidate.

+1
source

All Articles