我正在使用writeablebitmap的后备,并将其应用于图像,但图像由于某种原因没有更新。
我已经检查了内存并且后备缓冲区值已更改,但是将图像源设置为writeablebitmap不会改变任何内容。屏幕保持黑色。
这是我的计划:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Threading;
namespace RayTracer
{
class Main : Application
{
Window mainWindow;
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
CreateAndShowMainWindow();
}
public void CreateAndShowMainWindow()
{
mainWindow = new Window();
mainWindow.Title = "Writeable Bitmap";
mainWindow.Height = 480;
mainWindow.Width = 640;
mainWindow.ResizeMode = ResizeMode.NoResize;
mImage = new Image();
mWriteableBitmap = new WriteableBitmap(640, 480, 96, 96, PixelFormats.Rgb24, null);
mImage.Stretch = Stretch.None;
mImage.Margin = new Thickness(0);
mBytesPerPixel = (mWriteableBitmap.Format.BitsPerPixel + 7) / 8;
mStride = mWriteableBitmap.PixelWidth * mBytesPerPixel;
StackPanel myStackPanel = new StackPanel();
myStackPanel.Orientation = Orientation.Vertical;
myStackPanel.Height = 480;
myStackPanel.VerticalAlignment = VerticalAlignment.Top;
myStackPanel.HorizontalAlignment = HorizontalAlignment.Left;
myStackPanel.Children.Add(mImage);
mainWindow.Content = myStackPanel;
mainWindow.Show();
DispatcherTimer dispatcherTimer = new DispatcherTimer();
dispatcherTimer.Tick += new EventHandler(dispatcherTimer_Tick);
dispatcherTimer.IsEnabled = true;
dispatcherTimer.Interval = new TimeSpan(0, 0, 1);
dispatcherTimer.Start();
}
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
for (int i = 0; i < 480; i++)
{
for (int j = 0; j < 640; j++)
{
setPixel(j, i, Color.FromRgb(255, 255, 255));
}
}
mImage.Source = mWriteableBitmap; // image should be white but stays black
}
private Image mImage = null;
private WriteableBitmap mWriteableBitmap = null;
private int mBytesPerPixel = 0;
private int mStride = 0;
void setPixel(int x, int y, Color c)
{
int posX = x * mBytesPerPixel;
int posY = y * mStride;
unsafe
{
byte* backBuffer = (byte*)mWriteableBitmap.BackBuffer;
backBuffer[posY + posX] = c.R;
backBuffer[posY + posX + 1] = c.G;
backBuffer[posY + posX + 2] = c.B;
}
}
void clearScreen()
{
int totalBytes = mStride * 480;
unsafe
{
byte* backBuffer = (byte*)mWriteableBitmap.BackBuffer;
for (int i = 0; i < totalBytes; i++)
{
backBuffer[i] = 255;
}
}
}
}
internal static class EntryClass
{
[System.STAThread()]
private static void Main()
{
Main app = new Main();
app.Run();
}
}
}
答案 0 :(得分:2)
来自BackBuffer
MSDN页面上的备注:
仅在对Lock和Unlock的调用之间更新后台缓冲区 方法。如果您不遵循中所述的锁定/解锁工作流程 WriteableBitmap类备注,未定义的行为,如 撕裂,可能会发生。
所以你的Tick处理程序应如下所示:
private void dispatcherTimer_Tick(object sender, EventArgs e)
{
mWriteableBitmap.Lock();
for (int i = 0; i < 480; i++)
{
for (int j = 0; j < 640; j++)
{
setPixel(j, i, Color.FromRgb(255, 255, 255));
}
}
mWriteableBitmap.AddDirtyRect(new Int32Rect(0, 0,
mWriteableBitmap.PixelWidth, mWriteableBitmap.PixelHeight));
mWriteableBitmap.Unlock();
mImage.Source = mWriteableBitmap; // image is white now
}