2

WinRT プロジェクトで WriteableBitmapEx を使用しています。ユーザーの画像ライブラリから WriteableBitmap に画像を読み込みます。ただし、その画像にすぐに書き込むことはできません。そうすると、画像自体で上書きされます(画像を非同期でロードし、その上に描画を上書きしているようです)。それを止める方法がわかりません( SetSource で Await を使用しようとしましたが、それは Async メソッドではありません)。

「Await Task.Delay(1000)」を使用しましたが、それは機能しますが、1000ミリ秒では十分な時間ではない場合があるため、ハッキーに思えます.ビットマップがロードされるまで待ってから続行してください。

誰かが私が間違っていることをトップから外したように見えたり、処理を行う前に WriteableBitmap が画像ライブラリからロードされていることを確認する方法を提案したりできますか? 作成したコード スニペットの例を次に示します。

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
4

3 に答える 3

8

このメソッドは、アプリのコンテンツから画像を読み込み、デコードして、すぐに使用できる 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;
   }
}

ところで、WinRT は現在、WriteableBitmapEx によって正式にサポートされています。;) http://kodierer.blogspot.de/2012/05/one-bitmap-to-rule-them-all.html

于 2012-05-05T18:50:47.517 に答える
2

OpenAsync が返されることは、ストリームが利用可能であることを意味するだけであり、データが実際にストリームから読み取られることを意味するわけではありません。したがって、最初に開く+読み取るの両方を行いたいと思われ、その後は問題ありません。

ReadAsync では最初にバッファを作成して渡す必要があると Filip が指摘したので、以下のスニペットを更新して、OpenReadAsync を実行して IRandomAccessStream を取得した後、DataReaderを使用して実際にストリームをバイト配列にロードするようにしました。

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));
于 2012-04-17T20:32:34.513 に答える
1

WB には、BitmapImage が開くのを待つイベントがないと思います。wb.SetSource() を呼び出す代わりに、BitmapDecoder/CreateAsync/GetPixelDataAsync/DetachPixelData を使用して、結果のバイト配列を WB のピクセル バッファーにコピーしてみます。次に、wb.Invalidate() を呼び出します。あるいは、Delay 呼び出しを Invalidate 呼び出しに置き換えるだけかもしれません。

于 2012-04-17T23:40:24.507 に答える