我围绕算法建立了一个GUI。为此,我有一个Window组件,里面包含一个Image组件。
Image组件(imgHolder)中的内容由BitmapImage对象(_image)给出,为了本示例的目的,该对象被初始化为:
_image = new BitmapImage();
_image.BeginInit();
_image.CacheOption = BitmapCacheOption.OnLoad;
_image.CreateOptions = BitmapCreateOptions.IgnoreImageCache;
_image.UriSource = new Uri("c:\\a1.bmp");
_image.EndInit();
imgHolder.Source = _image;
包含Window的主程序将在Matlab DLL文件中执行对算法函数之一的调用。这将运行算法的一次迭代,最后它将结果从上面将结果写入本地bmp文件(“c:\ a1.bmp”)。因此,图像的基础数据已经更新,我希望将其反映在imgHolder组件中。为此,每当我从函数返回时,我只是复制上面的代码。
这种方法的问题是算法每次运行将有大约100次迭代,所以这必须发生100次。这似乎不对。我将创建100个不同的位图图像,所有这些都来自同一个文件。
研究这个我发现可以使用内存流,但我想知道这是否会是一个彻底的改进,因为我似乎仍然需要在算法执行时创建100个图像。是不是可以以某种方式直接修改底层缓冲区?我听说GetPixel和SetPixel效率不高,因为每次调用它们都会设置锁定。是否有可能使用相同的_image对象执行此操作?如果这不是本地文件,我可以使用无缓存选项,它本身应该“工作”。由于锁定,对文件为本地的无缓存选项不起作用。
有没有人有更好的主意?
谢谢!
答案 0 :(得分:2)
我还不太清楚你是否可以访问位图的原始数据,或者它是否总是写入文件。既然你提到了SetPixel,我猜你有。
因此,您可以使用WritableBitmap作为_image.Source
,并通过其WritePixels方法之一循环更新其内容。
我刚刚尝试了以下示例,该示例使用简单模式在每次鼠标移动时更新图像。
XAML:
<Window ...>
<Grid>
<Image Name="image" />
</Grid>
</Window>
代码:
public partial class MainWindow : Window
{
private WriteableBitmap bitmap = new WriteableBitmap(100, 100, 96d, 96d, PixelFormats.Rgb24, null);
private byte[] buffer = new byte[30000];
public MainWindow()
{
InitializeComponent();
image.Source = bitmap;
}
private void OnMouseMove(object sender, MouseEventArgs e)
{
Point pos = e.GetPosition(image);
int offset = (int)pos.X + (int)pos.Y;
for (int i = 0; i < buffer.Length; i++)
{
buffer[i] = (byte)(i + offset);
}
bitmap.WritePixels(new Int32Rect(0, 0, 100, 100), buffer, 300, 0);
}
}