vb.net - 在 Visual Basic 中加载多达 32768 个图片框
问题描述
我有一个应用程序正在加载 32^2 到 32768 个 8x8 像素图片框。所有图片框都在屏幕上,所以我需要全部加载,不能只加载一些。
就目前而言,我的程序甚至不会运行。有没有更好的方法来加载这么多图片框?
我想和你分享我的项目,但我不知道如何......
不过谢谢!
解决方案
使用这种设计,您可能会遇到 MemoryOverflowException。从它的声音来看,如果是这种情况,您可能正在尝试渲染某种地图,那么这个答案适合您(否则就忽略它)。
在较高的级别上,您应该只创建在任何给定时间可以在屏幕上显示的 PictureBox 控件的数量。您可以使用以下函数进行计算:
Private Function CalculateSizeToFitParent(ByVal parent As Control, ByVal childSize As Size) As Size
Return New Size(parent.Width \ childSize.Width, parent.Height \ childSize.Height)
End Sub
您可以这样实现它以创建一个 PictureBox 来填充当前表单的可见区域:
Dim pictureBoxSize As Size = New Size(8, 8)
Dim visibleArea(pictureBoxSize.Width - 1, pictureBoxSize.Height - 1) As PictureBox
Dim numberOfPictureBoxes As Size = CalculateSizeToFitParent(Me, pictureBoxSize)
For x As Integer = 0 To numberOfPictureBoxes.Width - 1
For y As Integer = 0 To numberOfPictureBoxes.Height - 1
visibleArea(x, y) = New PictureBox() With {
.Location = New Point(x * pictureBoxSize.Width, y * pictureBoxSize.Height)
.Size = pictureBoxSize
}
Me.Controls.Add(visibleArea(x, y))
Next
Next
下一部分分为两部分:
- 您需要跟踪当前可见的左上角在哪里
- 您将需要在地图的相应可视区域中重新加载图像。
这假设您有一个存储图像的二维数组。请注意,您不会重新创建 PictureBox 控件,而只是重新加载现有控件的图像:
Private _currentLocation As Point = New Point(0, 0) ' If you're starting somewhere else change it here
Public Property CurrentLocation As Point
Get
Return _currentLocation
End Get
Set(ByVal value As Point)
If (value <> _currentLocation) Then
_currentLocation = value
Me.OnCurrentLocationChanged()
End If
End Set
End Property
Protected Overridable Sub OnCurrentLocationChanged()
RaiseEvent CurrentLocationChanged(Me, EventArgs.Empty)
End Sub
Public Event CurrentLocationChanged(ByVal sender As Object, ByVal e As EventArgs)
Private Sub MyForm_CurrentLocationChanged(ByVal sender As Object, ByVal e As EventArgs) Handles Me.CurrentLocationChanged
If (visibleArea Is Nothing) Then
Throw New Exception("The visible area has not been generated yet.")
End If
If (_currentLocation Is Nothing) Then
Throw New Exception("The CurrentLocation cannot be null.")
End If
Dim widthUpperBounds As Integer = My2DArrayOfImageLocations.GetUpperBounds(0) - 1
Dim heightUpperBounds As Integer = My2DArrayOfImageLocations.GetUpperBounds(1) - 1
For x As Integer = 0 To visibleArea.GetUpperBounds(0) - 1
For y As Integer = 0 To visibleArea.GetUpperBounds(1) - 1
If (x + _currentLocation.Width > widthUpperBounds OrElse y + _currentLocation.Height) Then
'This "block" is outside the view area (display a blank tile?)
Else
visibleArea(x, y).Load(My2DArrayOfImageLocations(x + _currentLocation.Width, y + _currentLocation.Height))
End If
Next
Next
End Sub
现在,无论何时您重置 CurrentLocation 属性(但是您会这样做,例如箭头键、asdw 等),它将重新绘制地图的可见区域。
更新 请注意,我“自由输入”了这个例子,你可能需要稍微调整一下。经过一番思考,您可能还需要在加载图像时调用 PictureBox 的 Refresh 方法(我没有测试)。
推荐阅读
- javascript - 为什么我的数据表固定标题不起作用/
- python - conda 卸载和安装时软件包不匹配
- hive - 如何在 Hive 的当前层中使用查询结果?
- python - 如何启动 Python 游戏循环?
- autodesk-forge - Blazor webassembly http 默认标头 Forge Design Automation
- python - django.db.utils.ProgrammingError:关系“blog_category”不存在
- html - 如何防止我的桌子随着滚动而移动以及如何使其居中?
- php - 无法通过 PHP 中的 Here Map API 生成令牌
- python - 计算具有两个层次结构的数据的 14 天滚动平均值
- node.js - npm run build 总是在 Azure 应用服务推送后手动运行