充分披露:我没有正规的编程培训,但已经尝试了很多年。
我正在制作一个用于教育/医学成像的窗口应用程序。我想要做的事情之一是让用户能够滚动通过CT扫描,也就是由100+图像组成的图像集。(为了节省内存,我已经用压缩的.jpegs捕获了CT扫描,所以不需要担心dicom格式)我有一个工作解决方案,它使用垂直滚动条来允许用户选择要在picturebox中观察的CT扫描的哪个部分。图像只是按数字命名,例如。1.jpeg,2.jpeg.110.jpeg。
vsbCT =垂直滚动条
pbxCTScan = Picturebox
Private Sub VsbCT_ValueChanged(sender As Object, e As EventArgs) Handles vsbCT.ValueChanged
Dim CTScanFileName as String
CTScanFileName = "D:\CT_Images\" & CStr(vsbCT.Value) & ".jpeg"
pbxCTScan.Image = Image.FromFile(CTScanFileName)
End Sub这很好地工作,至少在最初的时候是这样的。然而,在visual环境中进行测试时,循环浏览许多图像似乎会导致程序崩溃。我不知道造成崩溃的原因,但是由于它最初是按预期工作的,并且崩溃是因为我查看了多少图像,以及我滚动的速度有多快,所以我想知道内存是否存在某种形式的问题。
问题是:这是否完成这项工作最有效的方法?我已经考虑过在数组或列表中输入所有图像并从其中显示它们,但是这将消耗60 it的内存,并且看起来不像从磁盘读取它那样优雅。
任何帮助都将不胜感激!
诚挚的问候
dr_glacier
发布于 2018-05-18 21:42:58
我会解决你的问题的应用程序最终崩溃。对最有效的方式的要求是意见的主题,因此对它来说是非主题的,并且很可能会导致你的问题被关闭。
每次执行VsbCT_ValueChanged时,您都要创建一个新的映像。但是,您永远不会在旧映像上调用处置方法。从理论上讲,垃圾收集器会清理这一点,但是Image占用的大部分内存是非托管的,因此内存压力几乎不可能触发收集。也存在消耗的GDI句柄是有限资源的问题。这就是为什么建议您的代码调用在一次性对象不再需要时立即对其进行释放,以便释放所消耗的资源。
处理这一问题的方法是使用扩展方法。
Public Module Utilities
<Extension()>
Public Sub SwapImage(pb As PictureBox, newImage As Image)
If pb.Image IsNot Nothing Then
pb.Image.Dispose()
End If
pb.Image = newImage
End Sub
End Module 然后,这一声明:
pbxCTScan.Image = Image.FromFile(CTScanFileName)将改为:
pbxCTScan.SwapImage(Image.FromFile(CTScanFileName))https://stackoverflow.com/questions/50417938
复制相似问题