【问题标题】:How to Convert BMP Image in PictureBox to Array of Bytes in VB6如何将PictureBox中的BMP图像转换为VB6中的字节数组
【发布时间】:2019-07-28 18:56:30
【问题描述】:

在旧版 VB6 应用程序中,我将 BMP 图像存储在 PictureBox 中。我可以使用以下方法将其保存到 BMP 文件中:

  SavePicture picBox.Picture, "BmpImage.bmp"

但是,我想要将 PictureBox 中的 BMP 图像保存到一个字节数组中。我需要存储整个 BMP,包括 BMP 标头。实际上,我想要将相同的数据写入 BMP 文件但在字节数组中,而无需写入和读取磁盘文件。

我在网上搜索过,但没有找到任何解决此特定问题的内容。


我确实找到了一个建议写入 MemoryStream 的link。所以我尝试了这个:

10  Dim bmpArray() As Byte
20  Dim memStream As New System.IO.MemoryStream

50  SavePicture picBox.Picture, memStream
60  bmpArray = memStream.GetBuffer

但是这不能编译。我为“System.IO.MemoryStream”得到“未定义用户定义的类型” 我已将 System 包含在我的参考列表中。我也尝试过声明为 New MemoryStream,但仍然出现“未定义用户定义类型”编译器错误。


我还查看了similar question,但是提供的解决方案仅将像素数据存储在数组中。

【问题讨论】:

  • 您尝试使用的代码用于 VB.Net,因此出现错误...
  • JonN,@Idle_Mind 指的是内存流代码。这在 VB6 中不存在。
  • 如果您可以选择编写 .NET 代码,您可以创建一个 VB.NET 类来执行您想要的任何操作,然后从 VB6 调用它。当然,要使其正常工作,还有一些初始设置开销,以及您必须进行的任何部署更改。
  • @Idle_Mind 是的,我怀疑这是因为第一个链接是 .NET 的解决方案,但我想试试看 MemoryStream 在 VB6 中是否可用。我希望这里有人知道如何在 VB6 中创建等效的内存流或其他方式将 PictureBox 转换为字节数组。
  • 做一些搜索。在 VB6 中有很多代码可以做到这一点,但这并不是很容易在这里发布的,因为有很多小步骤,每个步骤都应该有错误检查。这个网站更适合简单的问答,而不是请求除了微小的代码示例。

标签: arrays vb6 picturebox memorystream bmp


【解决方案1】:

如果您确实希望将 BMP 文件的确切内容作为字节数组,为什么不分步进行呢?

第 1 步:使用 SavePicture 写入临时文件。

第 2 步:使用普通文件 I/O 操作将临时文件读回数组。

第 3 步:删除临时文件

【讨论】:

  • 这就是我目前正在做的“变通”。但是,正如我在问题中所说,我想这样做而不必写入临时文件。我必须相信有一种方法可以在 VB6 中做到这一点,而无需写入磁盘。
  • 您为什么认为这是一种解决方法? PictuteBox 中图像的内存格式可能与位图格式的二进制表示不同。事实上,“BMP”格式的内容有多种变体。
  • 这是一种解决方法,因为在我的应用程序中此方案的要求之一是避免写入磁盘。添加的新功能的全部意义在于消除磁盘写入。
  • 还不错...很好奇写入磁盘的限制是什么?
  • 在项目的早期版本中,两个组件通过磁盘文件交换图像。其中一个组件是我的应用程序(VB6 中的 ActiveX EXE) 我的应用程序向其提供图像的另一个组件来自第 3 方。 3rd 方组件的更新版本现在直接通过内存接受图像。这样做是为了加快图像交换。因此,必须将图像写入磁盘才能将其放入内存,这违背了预期的设计改进。第 3 方希望我的应用程序直接在内存中传递图像,而不会浪费时间写入磁盘。
【解决方案2】:

GDI32 中有一些函数可以使从图像中获取数组变得简单。我不能在这里发布工作代码,因为我已经使用自定义类型等在汇编中编写了大部分代码,但我可以告诉您从GetDIBits() 开始搜索,其中“DI”代表设备无关。

这是一个声明:

Public Declare Sub GetDIBits Lib "gdi32" _
 (ByVal hDC As Long, _
  ByVal hBitmap As Long, _
  ByVal nStartScan As Long, _
  ByVal nNumScans As Long, _
  ByRef lpBits As Any, _
  ByRef lpBI As BITMAPINFO, _
  ByVal wUsage As Long)

使用图片框的.hDC

您将需要BITMAPINFOBITMAPINFOHEADER 等的定义,但听起来好像您可能已经有了这些。

【讨论】:

  • 我查找了 GetDIBits,根据提供的输入参数,它似乎有多种行为。我没有看到一个简单的调用场景,它会将整个 BMP 数组(包括标题和像素数据)作为字节数组返回。充其量看起来您需要分别检索 BMP 标头、调色板和像素数据,并自己以某种方式将它们组装成一个字节数组。这就是你的想法吗?
  • @JonN - 您可以创建带有适当标题的数组,然后将 GetDIBits 指向数组中数据所属的位置。完毕。除了作为文件或管道写入/读取之外,我不知道有什么方法可以为您构建 BMP 标头。
  • 标题的大小不会因所使用的特定 BMP 格式而异吗?不是有两个不同版本的标题和调色板部分的大小也可以不同,对吧?那么该技术是否会读取标题的某些部分,然后从中确定各种标题的大小并相应地为每个部分选择数组中的位置?
猜你喜欢
  • 1970-01-01
  • 2010-09-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-05
  • 1970-01-01
  • 2011-04-17
  • 2011-06-01
相关资源
最近更新 更多