0

user32.dll で syscall を使用して、クリップボードの内容を取得しようとしています。Print Screenからの画像データだと思います。

今、私はこれを持っています:

if opened := openClipboard(0); !opened {
    fmt.Println("Failed to open Clipboard")
}

handle := getClipboardData(CF_BITMAP)

// get buffer

img, _, err := Decode(buffer)

ハンドルを使用して、読み取り可能なバッファにデータを取得する必要があります。

AllenDang/w32 と github の atotto/clipboard からインスピレーションを得ました。以下は、atotto の実装に基づいて、テキストに対して機能します。

text := syscall.UTF16ToString((*[1 << 20]uint16)(unsafe.Pointer(handle))[:])

しかし、デコードできる画像データを含むバッファを取得するにはどうすればよいでしょうか?

[アップデート]

@kostix が提供したソリューションに従って、私は半分の作業例を一緒にハックしました。

image.RegisterFormat("bmp", "bmp", bmp.Decode, bmp.DecodeConfig)

if opened := w32.OpenClipboard(0); opened == false {
    fmt.Println("Error: Failed to open Clipboard")
}

//fmt.Printf("Format: %d\n", w32.EnumClipboardFormats(w32.CF_BITMAP))
handle := w32.GetClipboardData(w32.CF_DIB)
size := globalSize(w32.HGLOBAL(handle))
if handle != 0 {
    pData := w32.GlobalLock(w32.HGLOBAL(handle))
    if pData != nil {
        data := (*[1 << 25]byte)(pData)[:size]
        // The data is either in DIB format and missing the BITMAPFILEHEADER
        // or there are other issues since it can't be decoded at this point
        buffer := bytes.NewBuffer(data)
        img, _, err := image.Decode(buffer)
        if err != nil {
            fmt.Printf("Failed decoding: %s", err)
            os.Exit(1)
        }

        fmt.Println(img.At(0, 0).RGBA())
    }

    w32.GlobalUnlock(w32.HGLOBAL(pData))
}
w32.CloseClipboard()

AllenDang/w32 には必要なもののほとんどが含まれていますが、globalSize() のように自分で何かを実装する必要がある場合もあります。

var (
    modkernel32    = syscall.NewLazyDLL("kernel32.dll")
    procGlobalSize = modkernel32.NewProc("GlobalSize")
)

func globalSize(hMem w32.HGLOBAL) uint {
    ret, _, _ := procGlobalSize.Call(uintptr(hMem))

    if ret == 0 {
        panic("GlobalSize failed")
    }

    return uint(ret)
}

たぶん、誰かが BMP データを取得するための解決策を考え出すでしょう。その間、私は別の道を歩みます。

4

1 に答える 1