允许用户通过图片框快速循环 100 多张图像的最有效方法是什么
What's the most efficient way of allowing a user to rapidly cycle 100+ images through a picturebox
完全公开:我没有接受过正规的编程培训,但已经涉足多年。
我正在制作一个 windows 应用程序用于 education/medical 成像。我希望它做的一件事是使用户能够滚动浏览 CT 扫描,这是一个包含 100 多张图像的图像集。 (我已经在压缩的 .jpeg 中捕获了 CT 扫描以节省内存,因此无需担心 dicom 格式)我有一个工作解决方案,它使用垂直滚动条允许用户 select 哪个切片在图片框中观察的 CT 扫描图。图像仅由数字命名,例如。 1.jpeg, 2.jpeg...110.jpeg.
vsbCT = 垂直滚动条
pbxCTScan = 图片框
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 studio 环境中进行测试时,快速循环浏览许多图像似乎会导致程序崩溃。我不知道崩溃的原因,但由于它最初按预期工作并且崩溃是我查看的图像数量和滚动速度的函数,我想知道是否存在某种形式的内存问题。
问题如下:这是完成这个任务最有效的方法吗?我考虑过将所有图像输入数组或列表中并从那里显示它们,但这会消耗 60Mb 的内存,而且看起来不如从磁盘读取它优雅。
任何帮助将不胜感激!
此致
dr_glacier
我会解决您的应用程序最终崩溃的问题。对最有效方法的请求是意见主题,因此对于 SO 来说是题外话,可能会导致您的问题被关闭。
每次 VsbCT_ValueChanged
执行时您都在创建一个新图像。但是,您永远不会在旧图像上调用 Dispose 方法。理论上,垃圾收集器会清理它,但 Image 消耗的大部分内存是不受管理的,因此内存压力触发收集的可能性很小。还有消耗 GDI 句柄资源有限的问题。这就是为什么建议您的代码在不再需要一次性对象时立即调用 Dispose 以释放消耗的资源。
处理这个问题的方法是使用扩展方法。
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))
完全公开:我没有接受过正规的编程培训,但已经涉足多年。
我正在制作一个 windows 应用程序用于 education/medical 成像。我希望它做的一件事是使用户能够滚动浏览 CT 扫描,这是一个包含 100 多张图像的图像集。 (我已经在压缩的 .jpeg 中捕获了 CT 扫描以节省内存,因此无需担心 dicom 格式)我有一个工作解决方案,它使用垂直滚动条允许用户 select 哪个切片在图片框中观察的 CT 扫描图。图像仅由数字命名,例如。 1.jpeg, 2.jpeg...110.jpeg.
vsbCT = 垂直滚动条
pbxCTScan = 图片框
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 studio 环境中进行测试时,快速循环浏览许多图像似乎会导致程序崩溃。我不知道崩溃的原因,但由于它最初按预期工作并且崩溃是我查看的图像数量和滚动速度的函数,我想知道是否存在某种形式的内存问题。
问题如下:这是完成这个任务最有效的方法吗?我考虑过将所有图像输入数组或列表中并从那里显示它们,但这会消耗 60Mb 的内存,而且看起来不如从磁盘读取它优雅。
任何帮助将不胜感激!
此致
dr_glacier
我会解决您的应用程序最终崩溃的问题。对最有效方法的请求是意见主题,因此对于 SO 来说是题外话,可能会导致您的问题被关闭。
每次 VsbCT_ValueChanged
执行时您都在创建一个新图像。但是,您永远不会在旧图像上调用 Dispose 方法。理论上,垃圾收集器会清理它,但 Image 消耗的大部分内存是不受管理的,因此内存压力触发收集的可能性很小。还有消耗 GDI 句柄资源有限的问题。这就是为什么建议您的代码在不再需要一次性对象时立即调用 Dispose 以释放消耗的资源。
处理这个问题的方法是使用扩展方法。
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))