设置Image.Source后更新WritableBitmap

时间:2017-01-23 20:07:43

标签: c# wpf writablebitmap

我正在尝试使用WritableBitmap对位图图像进行像素级操作。但是我无法使其工作。我想要做的是在WritableBitmap之后操纵像素数据我用我的位图分配Image.Source属性。我用谷歌搜索,我发现的唯一一件事是调用bitmap.Invalidate()方法,但它似乎已被弃用,因为我无法在{{1}中找到该方法} class.following是我用来更新图像但没有运气的代码:

WritableBitmap

对此有何看法?

修改

我将不胜感激任何关于WPF中 FAST 2D绘图的其他方式的建议, wbitmap.Lock(); wbitmap.WritePixels(rect, pixels, stride, 0); wbitmap.AddDirtyRect(new Int32Rect(0, 0, width, height)); wbitmap.Unlock(); //given that i've already assigned image.Source with "wbitmap" image.InvalidateVisual(); 更好。

1 个答案:

答案 0 :(得分:1)

以下简单示例显示如何在将WriteableBitmap分配给图像控件的Source属性时连续编写WriteableBitmap。

XAML就是这样:

<Window ...>
    <Grid>
        <Image x:Name="image"/>
    </Grid>
</Window>

在后面的代码中有一个计时器,它使用随机像素颜色值每秒十次覆盖WriteableBitmap。请注意,您必须在Visual Studio项目属性中(在“构建”选项卡中)允许不安全的代码。

除了Lock / AddDirtyRect / Unlock,您也可以致电writePixels。但是,Lock方法还允许另一个非UI线程写入BackBuffer

public partial class MainWindow : Window
{
    private readonly WriteableBitmap bitmap
        = new WriteableBitmap(100, 100, 96, 96, PixelFormats.Bgr32, null);

    public MainWindow()
    {
        InitializeComponent();
        image.Source = bitmap;

        var timer = new DispatcherTimer { Interval = TimeSpan.FromSeconds(0.1) };
        timer.Tick += OnTimerTick;
        timer.Start();
    }

    private unsafe void OnTimerTick(object sender, EventArgs e)
    {
        int pixelValue = (int)DateTime.Now.Ticks & 0xFFFFFF;

        bitmap.Lock();
        var backBuffer = bitmap.BackBuffer;

        for (int y = 0; y < bitmap.PixelHeight; y++)
        {
            for (int x = 0; x < bitmap.PixelWidth; x++)
            {
                var bufPtr = backBuffer + bitmap.BackBufferStride * y + x * 4;
                *((int*)bufPtr) = pixelValue;
            }
        }

        bitmap.AddDirtyRect(new Int32Rect(0, 0, bitmap.PixelWidth, bitmap.PixelHeight));
        bitmap.Unlock();
    }
}