3

Image コントロールに接続されてWriteableBitmapいる Windows Phone 8 アプリケーションを使用しています。画像の各行をループし、一度に非同期でピクセルの行をペイントしてから、次の行をペイントするようにスケジュールします。ただし、基になるピクセル データを変更しても変更されたプロパティが起動されないように見えるため、コントロールは更新されません。画像ソースを同じピクセルから作成された新しい WriteableBitmap に設定すると、画像は正常に更新されますが、過剰な配列のコピーが多くなります。

void PaintImage(object state)
{
    // get my height, width, row, etc. from the state
    int[] bitmapData = new int[width];
    // load the data for the row into the bitmap

    Dispatcher.BeginInvoke(() =>
    {
        var bitmap = ImagePanel.Source as WriteableBitmap;
        Array.Copy(bitmapData, 0, bitmap.Pixels, row * width, bitmapData.Length);

        if (row < height - 1)
        {
            var newState = ... // create new state
            ThreadPool.QueueUserWorkItem(PaintImage, newState);
        }
    });
}

上記の Array.Copy の後にこれらの行を追加すると、ビットマップが徐々に画面に描画されます (ただし、実際には毎回ビットマップを置き換えるだけです)。

var newBitmap = new WriteableBitmap(width, height);
Array.Copy(bitmap.Pixels, newBitmap.Pixels, newBitmap.Pixels.Length);
ImagePanel.Source = newBitmap;

手動で WriteableBitmap にいくつかのプロパティ変更通知を発行させて、それを持つ Image にする必要があるようです。画像を ViewModel の WriteableBitmap にバインドすれば、この問題は解決すると思いますか?

4

2 に答える 2

3

汚い四角形を追加するだけです

 _myBitmap.Lock();
 _myBitmap.AddDirtyRect(new Int32Rect(0, 0, _myBitmap.PixelWidth, _myBitmap.PixelHeight));
 _myBitmap.Unlock();

または、バックグラウンド スレッドを使用している場合

 Application.Current.Dispatcher.InvokeAsync(() =>
    {
        _myBitmap.Lock();
        _myBitmap.AddDirtyRect(new Int32Rect(0, 0, _myBitmap.PixelWidth, _myBitmap.PixelHeight));
        _myBitmap.Unlock();
    });
于 2014-12-12T18:46:48.370 に答える
1

Invalidate() を呼び出して再描画を要求する必要があると思います。参照: http://msdn.microsoft.com/en-us/library/system.windows.media.imaging.writeablebitmap.invalidate(v=vs.95).aspx

于 2012-12-13T07:25:39.693 に答える