Reputation: 5967
I am trying to use WritableBitmap
to do some pixel level manipulation of bitmap images.But i can't get it working.What i want to do is manipulating pixel data of WritableBitmap
after i assign Image.Source
property with my bitmap.I googled and the only thing i found is call to bitmap.Invalidate()
method but it seems to be deprecated as i couldn't find that method in WritableBitmap
class.following is the code i am using to get the image updated but no luck:
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();
any thoughts on this?
EDIT
i would appreciate any suggestion for other way of FAST 2D drawing in WPF better that WritableBitmap
.
Upvotes: 0
Views: 2374
Reputation: 128061
The following simple example shows how to continuously write a WriteableBitmap while it is assigned to the Source property of an image control.
The XAML is just this:
<Window ...>
<Grid>
<Image x:Name="image"/>
</Grid>
</Window>
In code behind there is a timer that overwrites the WriteableBitmap ten times per second with a random pixel color value. Note that you have to allow unsafe code in the Visual Studio Project Properties (in the Build tab).
Alternatively to Lock
/AddDirtyRect
/Unlock
you could also call WritePixels
. However, the Lock
approach also allows that another, non-UI thread writes to the 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();
}
}
Upvotes: 2