2024.08.05

C++我写的不是很好，混合项目的基础代码是我刚开始写C++的时候的遗产，能用也就没有在意。

在C++里计算完成的图像指针，如果直接修改用C#这边传递过来的图像，不合适，如果只是单纯的clone,那么在用opencv跑完之后，指针会因为是局部变量的问题，在函数调用结束之后，生命周期结束，就销毁掉，C#这边拿到图像指针就会出现  *AccessViolationException* 。

当时经验不足，直接new 一块内存，然后在传出来，用完之后再加一个函数来delete掉这块内存。

在后面接触的项目，主从逻辑就变了，以C++为主体，C#这边不管这个值，只做接收和显示，处理逻辑也和这快不一样。

梳理了一下思路，其实只要把输出的图像指针从局部变量修改为全局即可，也就是一个函数导出，4k*5k的图像我大概会浪费40ms的样子。同时快速内存创建又删除，会产生大量的内存碎片。

在之后我将图像指针拿到，又转换成writebitmap,最后再赋值为image显示的过程，又要创建和销毁大量的writebitmap，频繁触发GC。

其实可以只写数据，而不频繁创建对象，这样会增加对CPU的负担。

一顿操作猛如虎，节约的时间不超过100ms。使用体验上就是一些本来需要频繁滑动计算的值，可以用一个相对可以拖动的视角来看结果。

聊胜于无。

不过因为降低了频繁创建内存，不用就mat不用就 release掉，波动性会小很多



太麻烦了，不如直接让用户关掉软件，重新打开。



----

目前来说，从 C++ 传入图像数据到 C# 显示通常有两种方案：

1. ***\*使用 Windows Forms 和 PictureBox\****：    

   最简单的方法是不断创建新的 `Bitmap` 对象，然后将其赋值给 `PictureBox` 控件。这种方法实现简单，但性能较差，因为频繁创建和销毁 `Bitmap` 对象会导致大量的内存分配和释放。  

   优化的方案是使用 `BitmapData` 和 `LockBits` 方法来直接操作 `Bitmap` 的内存，从而只写入数据而不重新创建 `Bitmap` 对象。这种方式类似于 `WriteableBitmap`，可以显著提高性能。  Windows Forms 主要依赖 CPU 进行图像渲染，缺乏 GPU 加速，在处理复杂图像或高分辨率图像时性能较低。 

2. ***\*使用 WPF 和 Image\****：    

   WPF 提供了 `WriteableBitmap` 类，可以直接操作图像的内存缓冲区。通过锁定和解锁 `WriteableBitmap`，可以高效地更新图像数据。    

   WPF 的渲染管线使用 GPU 加速，在图像绘制和缩放时性能更高。这是 WPF 和 Windows Forms 在处理图像时性能差异最大的地方。使用 `PictureBox` 时，所有的绘制和缩放操作都由 CPU 完成，而 WPF 则利用了 GPU 的强大计算能力。   

   WPF 默认使用双缓冲机制，减少了屏幕闪烁并提高了渲染效率。这虽然需要额外的内存，但通过 GPU 加速，整体性能更高。



