如何在Golang中从Windows的`syscall`加载图像资源?

huangapple go评论90阅读模式
英文:

How to load image resource from windows `syscall` in golang?

问题

我正在使用go-bindata编写一个使用golang程序,将图像资源嵌入其中,并使用Asset(string) ([]byte, error)函数访问资源。但是我的现有库代码如下:

func NewIconFromFile(filePath string) (uintptr, error) {
    absFilePath, err := filepath.Abs(filePath)
    if err != nil {
        return 0, err
    }
    hicon, _, _ := LoadImage.Call(
        0,
        uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(absFilePath))),
        IMAGE_ICON,
        0,
        0,
        LR_DEFAULTSIZE|LR_LOADFROMFILE)
    if hicon == 0 {
        return 0, errors.New("load image failed: " + filePath)
    }
    return hicon, nil
}

我该如何重写这个函数:

func NewIconFromRawBytes(imgBytes []byte) (uintptr, error)

以便支持从[]byte加载图像?有什么帮助吗?谢谢。

编辑:有一个类似的C++版本问题,我该如何将其移植到golang中?

英文:

I am writing a golang program using go-bindata to embed the image resources, and use the Asset(string) ([]byte, error) function to access resources. But my existing library codes go like this:

func NewIconFromFile(filePath string) (uintptr, error) {
    absFilePath, err := filepath.Abs(filePath)
    if err != nil {
	    return 0, err
    }
    hicon, _, _ := LoadImage.Call(
	    0,
	    uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(absFilePath))),
	    IMAGE_ICON,
	    0,
	    0,
	    LR_DEFAULTSIZE|LR_LOADFROMFILE)
    if hicon == 0 {
	    return 0, errors.New("load image failed: " + filePath)
    }
    return hicon, nil
}

How can I rewrite this functions to:

 func NewIconFromRawBytes(imgBytes []byte) (uintptr, error) 

so it can support for loading images from []byte ? Any helps? thanks.

Edit: There is a similar c++ version question, how can I port it to golang.

答案1

得分: 1

LoadImage()处理的是内置在Windows可执行文件中的Windows资源。go-bindata似乎不处理这些资源,而直接使用Go来处理并不容易。

如果你想要编写一个NewIconFromRawBytes()函数,从内存中创建一个HICON,你需要使用一个名字有点令人困惑的CreateIconFromResourceEx()函数。如果你这样做,你可能需要记住这个答案中的信息

然而,如果这是一张图片而不是图标,并且你想要得到一个HBITMAP,你需要做更多的工作,涉及到CreateDIBSection()函数。这个答案展示了该如何做,不过理解起来可能会有点困难。需要特别注意的是,CreateDIBSection()会为图像分配内存,所以你需要将它从Go语言复制到提供的内存位置。

顺便提一下:如果你有一个*image.RGBA*image.NRGBA,如果你想将其放入HBITMAP中,你需要翻转字节的顺序,因为Windows期望字节的顺序是BGRA,而不是RGBA

英文:

LoadImage() deals with Windows resources, which are built into Windows executables directly. go-bindata doesn't seem to deal in these, and doing this with Go directly isn't trivial.

If you want to be able to write a NewIconFromRawBytes() that creates an HICON from memory, you'll need to use the confusingly-named CreateIconFromResourceEx() function. If you do that, you may want to keep the info in the answer here in mind.

If, however, this is an image instead of an icon and you want an HBITMAP out of it, you have a bit more work to do involving the CreateDIBSection() function. The answer here shows what to do, though understanding it may be a bit harder. Of important note is that CreateDIBSection() allocates the image memory for you, so you'll have to copy it from Go to the memory location provided.

Side note: if you have a *image.RGBA or *image.NRGBA, you'll need to flip the bytes around if you want to shove that into an HBITMAP, as Windows expects the bytes in BGRA order, not RGBA order.

huangapple
  • 本文由 发表于 2017年3月17日 11:51:10
  • 转载请务必保留本文链接:https://go.coder-hub.com/42848917.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定