// NewScreenshot will take a screenshot of the screen and convert it to an image.Image func NewScreenshot() image.Image { // Temporarily unbind the currently active canvas (glReadPixels reads the active framebuffer, not the main one.) canvases := GetCanvas() SetCanvas() w, h := int32(screen_width), int32(screen_height) screenshot := image.NewRGBA(image.Rect(0, 0, int(w), int(h))) stride := int32(screenshot.Stride) pixels := make([]byte, len(screenshot.Pix)) gl.ReadPixels(pixels, 0, 0, int(w), int(h), gl.RGBA, gl.UNSIGNED_BYTE) // OpenGL sucks and reads pixels from the lower-left. Let's fix that. for y := int32(0); y < h; y++ { i := (h - 1 - y) * stride copy(screenshot.Pix[y*stride:], pixels[i:i+w*4]) } // Re-bind the active canvas, if necessary. SetCanvas(canvases...) return screenshot }
// NewImageData will create an image from the canvas data. It will return an error // only if the dimensions given are invalid func (canvas *Canvas) NewImageData(x, y, w, h int32) (image.Image, error) { if x < 0 || y < 0 || w <= 0 || h <= 0 || (x+w) > canvas.width || (y+h) > canvas.height { return nil, fmt.Errorf("Invalid ImageData rectangle dimensions.") } prev_canvas := GetCanvas() SetCanvas(canvas) screenshot := image.NewRGBA(image.Rect(int(x), int(y), int(w), int(h))) stride := int32(screenshot.Stride) pixels := make([]byte, len(screenshot.Pix)) gl.ReadPixels(pixels, int(x), int(y), int(w), int(h), gl.RGBA, gl.UNSIGNED_BYTE) for y := int32(0); y < h; y++ { i := (h - 1 - y) * stride copy(screenshot.Pix[y*stride:], pixels[i:i+w*4]) } SetCanvas(prev_canvas...) // The new ImageData now owns the pixel data, so we don't delete it here. return screenshot, nil }