//export hookRequestImage func hookRequestImage(imageFunc unsafe.Pointer, cid *C.char, cidLen, cwidth, cheight C.int) unsafe.Pointer { f := *(*func(imgId string, width, height int) image.Image)(imageFunc) id := unsafeString(cid, cidLen) width := int(cwidth) height := int(cheight) img := f(id, width, height) var cimage unsafe.Pointer rect := img.Bounds() width = rect.Max.X - rect.Min.X height = rect.Max.Y - rect.Min.Y cimage = C.newImage(C.int(width), C.int(height)) var cbits []byte cbitsh := (*reflect.SliceHeader)((unsafe.Pointer)(&cbits)) cbitsh.Data = (uintptr)((unsafe.Pointer)(C.imageBits(cimage))) cbitsh.Len = width * height * 4 // RGBA cbitsh.Cap = cbitsh.Len i := 0 for y := 0; y < height; y++ { for x := 0; x < width; x++ { r, g, b, a := img.At(x, y).RGBA() *(*uint32)(unsafe.Pointer(&cbits[i])) = (a>>8)<<24 | (r>>8)<<16 | (g>>8)<<8 | (b >> 8) i += 4 } } return cimage }
// Snapshot returns an image with the visible contents of the window. // The main GUI thread is paused while the data is being acquired. func (win *Window) Snapshot() image.Image { // TODO Test this. var cimage unsafe.Pointer gui(func() { cimage = C.windowGrabWindow(win.addr) }) defer C.delImage(cimage) // This should be safe to be done out of the main GUI thread. var cwidth, cheight C.int C.imageSize(cimage, &cwidth, &cheight) var cbits []byte cbitsh := (*reflect.SliceHeader)((unsafe.Pointer)(&cbits)) cbitsh.Data = (uintptr)((unsafe.Pointer)(C.imageBits(cimage))) cbitsh.Len = int(cwidth * cheight * 8) // RRGGBBAA cbitsh.Cap = cbitsh.Len image := image.NewRGBA(image.Rect(0, 0, int(cwidth), int(cheight))) l := int(cwidth * cheight * 4) for i := 0; i < l; i += 4 { var c uint32 = *(*uint32)(unsafe.Pointer(&cbits[i])) image.Pix[i+0] = byte(c >> 16) image.Pix[i+1] = byte(c >> 8) image.Pix[i+2] = byte(c) image.Pix[i+3] = byte(c >> 24) } return image }