我正在尝试调整我的WPF技能,并决定现在是时候让一个writablebitmap动态加载段(这样用户可以立即看到加载到整个位图的部分内容)
问题是我现在正在编辑后台缓冲区,但是当我调用AddDiryRect时,没有任何反应。
我已经设法正确设置了背景工作者,但我相信我的不安全代码出错了(我第一次使用它时)。
澄清我已经简化了一点,(删除了不相关的字段等)。
首先,我创建了一个能够将指针存储到后备缓冲区的类:
public class BgWorkerMapProperties
{
public IntPtr pBackBuffer;
public int Stride;
public BgWorkerMapProperties(WriteableBitmap wb)
{
pBackBuffer = wb.BackBuffer;
Stride = wb.BackBufferStride;
}
}
在.xaml.cs类中我有以下内容:
public WriteableBitmap WorldMap_wb = new WriteableBitmap(256 * 7, 256 * 6, 96, 96, PixelFormats.Bgr32, null);
BackgroundWorker BgWorkerMap = new BackgroundWorker();
public BgWorkerMapProperties BgWorker;
public Page1()
{
InitializeComponent();
BgWorkerMap.WorkerReportsProgress = true;
BgWorkerMap.DoWork += BgWorkerMap_DoWork_Handler;
BgWorkerMap.ProgressChanged += BgWorkerMap_ProgressChanged_Handler;
img_WorldMap.Source = WorldMap_wb;
WorldMap_wb.Lock();
BgWorker = new BgWorkerMapProperties(WorldMap_wb);
BgWorkerMap.RunWorkerAsync(BgWorker);
}
private void BgWorkerMap_DoWork_Handler(object sender, DoWorkEventArgs args)
{
BackgroundWorker worker = sender as BackgroundWorker;
while (true)
{
BaseBitmap.AddMapFilePixelsToBitmapFromBuffer();
BgWorker.X = 0;
BgWorker.Y = 0;
worker.ReportProgress(0, BgWorker);
break;
}
}
private void BgWorkerMap_ProgressChanged_Handler(object sender, ProgressChangedEventArgs args)
{
WorldMap_wb.AddDirtyRect(new Int32Rect(BgWorker.X, BgWorker.Y, 256, 256));
WorldMap_wb.Unlock();
MessageBox.Show("BgWorker breaked, WB is Unlocked");
}
最后是不安全的代码:
public static void AddMapFilePixelsToBitmapFromBuffer()
{
unsafe
{
var backBuffer = (int*)bgWorker.pBackBuffer;
//Write a mapfile into it´s position
for (int x = 0; x < 256; x++)
{
for (int y = 0; y < 256; y++)
{
// Find the address of the pixel to draw.
int Bufferindex = x + (y * (bgWorker.Stride / 4));
// Compute the pixel's color.
color_data = 255 << 16; // R
color_data |= 255 << 8; // G
color_data |= 255 << 0; // B
}
// Assign the color data to the pixel.
backBuffer[Bufferindex] = color_data;
}
}
}
对于任何花时间阅读本文的人来说,我都非常高兴!
感谢WPF爱好者的推进!
答案 0 :(得分:2)
我相信您的不安全代码正在尝试写入错误的地址。 (X *步幅,Y * 4)? 确保指向backbuffer的指针是您尝试设置的实际数据类型(int?)。 如果您直接使用整数,则不需要执行“* 4”位,因为您的颜色(假设后备缓冲区正确对齐)将对应于一个'int'而不是四个。
另外,我建议直接索引,而不是做“(int )currentBackBuffer” 这是代码的修改版本,我认为应该如何。
public static void AddMapFilePixelsToBitmapFromBuffer()
{
unsafe
{
var backBuffer = (int*)bgWorker.pBackBuffer;
//Write a mapfile into it´s position
for (int x = 0; x < 256; x++)
{
for (int y = 0; y < 256; y++)
{
var index = x + (y * bgWorker.Width); // Assuming there's a width property somewhere, (Otherwise, this should be the same as Stride / 4)
var pixelColour = GetPixelColour(array[index]);
// TODO: Find out which value to set.
// is color_data actually pixelColour?
// what type is pixelColour?
// are you working with ARGB, BGRA or RGB?
backBuffer[index] = pixelColour;
}
}
}
}
请注意,我在那里留下了“TODO:”,因为我不确定你到底想要做什么。
编辑: 适用于我的示例代码: MainWindow(Xaml):http://pastebin.com/rVNzMwWy MainWindow(cs):http://pastebin.com/Qrmqd8kY