【问题标题】:Add bitmap to resource将位图添加到资源
【发布时间】:2013-10-15 15:18:56
【问题描述】:

我正在尝试将压缩位图添加为另一个可执行文件的资源,但遇到了错误。错误是:

Value of type 'System.Drawing.Bitmap' cannot be converted to '1-dimensional array of System.Drawing.Bitmap'

这是我的伪代码:

模块1:

    Imports System.Runtime.InteropServices
Module ResourceWriter
    Private Function ToPtr(ByVal data As Object) As IntPtr
        Dim h As GCHandle = GCHandle.Alloc(data, GCHandleType.Pinned)
        Dim ptr As IntPtr
        Try
            ptr = h.AddrOfPinnedObject()
        Finally
            h.Free()
        End Try
        Return ptr

    End Function

    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Function UpdateResource(ByVal hUpdate As IntPtr, ByVal lpType As String, ByVal lpName As String, ByVal wLanguage As UShort, ByVal lpData As IntPtr, ByVal cbData As UInteger) As Boolean
    End Function
    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Function BeginUpdateResource(ByVal pFileName As String, <MarshalAs(UnmanagedType.Bool)> ByVal bDeleteExistingResources As Boolean) As IntPtr
    End Function
    <DllImport("kernel32.dll", SetLastError:=True)> _
    Private Function EndUpdateResource(ByVal hUpdate As IntPtr, ByVal fDiscard As Boolean) As Boolean
    End Function

    Public Function WriteResource(ByVal filename As String, ByVal bmp As Bitmap()) As Boolean

        Try
            Dim handle As IntPtr = BeginUpdateResource(filename, False)
            Dim file1 As Bitmap() = bmp
            Dim fileptr As IntPtr = ToPtr(file1)
            Dim res As Boolean = UpdateResource(handle, "BitMaps", "0", 0, fileptr, Convert.ToUInt32(file1.Length))
            EndUpdateResource(handle, False)
        Catch ex As Exception
            Return False
        End Try
        Return True

    End Function
End Module

在表单中,在按钮下:

'...here's code to compress the image, commented out for now
Dim bmp1 As Bitmap = Compressed
WriteResource("C:\Users\Admin\Desktop\Testfile.exe", bmp1)

但它不起作用。我应该对模块或按钮下的代码进行哪些更改?我看到我应该在将图像放入资源之前将 System.Drawing.Bitmap 转换为 1 维数组,但是如何?

非常感谢任何帮助:)

编辑:

我现在已经尝试了从 google 和 MSDN 找到的所有答案,但我无法弄清楚。因此,如果有人可以展示如何做到这一点,我将非常感激.. 这是我尝试过的一种方法。

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        '...
        Dim bmp1 As Bitmap = Compressed
        Dim Converted = ConvertToByteArray(bmp1)
        WriteResource("C:\Users\Admin\Desktop\Testfile.exe", Converted)
    End Sub
    Public Shared Function ConvertToByteArray(ByVal value As Bitmap) As Byte()
        Dim bitmapBytes As Byte()
        Using stream As New System.IO.MemoryStream
            value.Save(stream, value.RawFormat)
            bitmapBytes = stream.ToArray
        End Using
        Return bitmapBytes
    End Function

是的,我在 Module1 中将 Bitmap() 更改为 Byte();但它在运行时返回了"Value cannot be NULL"

我也尝试将其保存为IO.MemoryStream,然后转换为字节,但没有成功。

所以如果任何人可以告诉我如何做到这一点,那就太好了。

【问题讨论】:

  • 如果你想写一个位图,你为什么要把它们的数组传递给 WriteResource?
  • 究竟是什么错误?将鼠标悬停在位图字节上-它有多大(或检查返回)...您是否更改了 WriteResource 中UpdateResource 的参数?我想我知道出了什么问题,但是Didn't success 对于通过 cmets 进行调试非常模糊

标签: arrays vb.net bitmap resources


【解决方案1】:

您通过在此处类型名称后面加上 () 将参数声明为位图数组:

Public Function WriteResource(ByVal filename As String, ByVal bmp As Bitmap()) As Boolean

如果你不希望它是一个数组,去掉 ():

Public Function WriteResource(ByVal filename As String, ByVal bmp As Bitmap) As Boolean

【讨论】:

  • 我已经尝试过这个,以及许多其他的组合,但是我会在模块中出现错误。这:Dim res As Boolean = UpdateResource(handle, "BitMaps", "0", 0, fileptr, Convert.ToUInt32(file1.Length))
  • @user2404495 但 file1 的长度是数组的大小而不是要写入的字节数,因此分配该错误实际上使事情变得更糟......或者至少没有解决任何问题。
  • 这里的代码离工作还有很长的路要走。例如,从内存而不是实际的位图文件写入托管位图数据不会产生工作资源。您应该尝试将位图上的 .Save 调用到 MemoryStream 中,并改用 MemoryStream 中的字节(使用 GetBuffer)。
【解决方案2】:

Ryan 的回答很好地涵盖了您遇到的第一个问题(Dim file1 As Bitmap() = bmp 也是错误的);第二个是你掩盖了一个不同的问题。

如果您参考UpdateResource on MSDN,您会看到cbdata 是要写入的字节数,即位图的字节数。您的代码正在传递数组的大小。此外,lpData 应该是指向数据的长指针,也是“Note that this is the raw binary data to be stored”。你不能像你试图做的那样只传递一个位图。

位图类的保存方法可以让您保存到内存流,从中可以获取字节和字节计数并将其提供给 UpdateResource。

【讨论】:

  • 好吧..我可以用 bmp1.Save("...") 保存 bmp1,所以错误是添加资源。在将文件添加到资源之前将文件保存到磁盘会更容易吗?有人可以展示一些与我的代码相关的简单示例吗?没有一个答案没有帮助。
  • 研究 MSDN 上的页面以了解您需要做什么。如果保存到磁盘是最好的第一步,我们都不会提到将其保存到 Memorystream。将代码放在一起以获取您的位图 -> memstream -> byte() 并为您遇到的任何问题发布代码。
  • 更新了帖子。没有成功将其转换为 bytearray 也没有将其保存到 memstream + 然后保存到字节......
  • 仍在寻求帮助,尚未成功:\
猜你喜欢
  • 2013-07-26
  • 2011-04-11
  • 2018-07-16
  • 2013-05-14
  • 1970-01-01
  • 2018-06-03
  • 1970-01-01
  • 2011-03-17
  • 2014-05-27
相关资源
最近更新 更多