3

我有一个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 触发一些属性更改通知,以便拥有它的图像。我猜如果我将图像绑定到 ViewModel 中的 WriteableBitmap,这个问题会消失吗?

4

2 回答 2

3

Just add a dirty rectangle

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

or if you are on a background thread

 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 回答