前端之家收集整理的这篇文章主要介绍了
Go语言实现AndroidFramebuffer屏幕截图功能,
前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
package main
/***********
作者:红猎人
***********/
import (
"os"
"syscall"
"fmt"
"unsafe"
/*
"image/png"
"bytes"
*/
)
var (
FBIOGET_VSCREENINFO = 0x4600
)
type fbBitfield struct {
offset uint32 /* beginning of bitfield */
length uint32 /* length of bitfield */
msb_right uint32 /* != 0 : Most significant bit is */
}
type fbVarInfo struct {
xres uint32 /* visible resolution */
yres uint32
xres_virtual uint32 /* virtual resolution */
yres_virtual uint32
xoffset uint32 /* offset from virtual to visible */
yoffset uint32 /* resolution */
bits_per_pixel uint32 /* guess what */
grayscale uint32 /* 0 = color,1 = grayscale,*/
/* >1 = FOURCC */
red fbBitfield /* bitfield in fb mem if true color,*/
green fbBitfield /* else only length is significant */
blue fbBitfield
transp fbBitfield /* transparency */
nonstd uint32 /* != 0 Non standard pixel format */
activate uint32 /* see FB_ACTIVATE_* */
height uint32 /* height of picture in mm */
width uint32 /* width of picture in mm */
accel_flags uint32 /* (OBSOLETE) see fb_info.flags */
/* Timing: All values in pixclocks,except pixclock (of course) */
pixclock uint32 /* pixel clock in ps (pico seconds) */
left_margin uint32 /* time from sync to picture */
right_margin uint32 /* time from picture to sync */
upper_margin uint32 /* time from sync to picture */
lower_margin uint32
hsync_len uint32 /* length of horizontal sync */
vsync_len uint32 /* length of vertical sync */
sync uint32 /* see FB_SYNC_* */
vmode uint32 /* see FB_VMODE_* */
rotate uint32 /* angle we rotate counter clockwise */
colorspace uint32 /* colorspace for FOURCC-based modes */
reserved [4]uint32 /* Reserved for future compatibility */
}
func main() {
fb,err := os.Open("/dev/graphics/fb0")
if err != nil {
panic("can't open file /dev/fb0")
}
defer fb.Close()
fmt.Printf("file open %v \n",fb.Fd())
var varInfo fbVarInfo
_,_,errno := syscall.RawSyscall(syscall.SYS_IOCTL,fb.Fd(),uintptr(FBIOGET_VSCREENINFO),uintptr(unsafe.Pointer(&varInfo)))
if errno != 0 {
fmt.Println(errno)
panic("can't ioctl ... ")
}
fmt.Printf("width = %d height = %d\n",varInfo.xres,varInfo.yres)
fmt.Printf("xoffset = %d yoffset = %d\n",varInfo.xoffset,varInfo.yoffset)
fmt.Printf("depth = %d\n",varInfo.bits_per_pixel/8)
// func Mmap(fd int,offset int64,length int,prot int,flags int) (data []byte,err error)
bpp := varInfo.bits_per_pixel / 8
size := varInfo.xres * varInfo.yres * bpp
offset := varInfo.xoffset * bpp + varInfo.xres * bpp * varInfo.yoffset
mapsize := size + offset
fmt.Printf("mapsize = %d\n",mapsize)
data,err := syscall.Mmap(int(fb.Fd()),int(mapsize),syscall.PROT_READ,syscall.MAP_PRIVATE)
if err != nil {
panic("map Failed ...")
}
defer syscall.Munmap(data)
/*
// save as png image.
//
// func Encode(w io.Writer,m image.Image) error
// m := image.NewRGBA(image.Rect(0,640,480))
screen := data[offset :]
m,err := png.Decode(bytes.NewBuffer(screen))
if err != nil {
panic("decode fail...")
}
output,err := os.OpenFile("/sdcard/screenshot.png",os.O_WRONLY | os.O_CREATE,0666)
if err != nil {
panic("can't open file /sdcard/screenshot.png")
}
defer output.Close()
err = png.Encode(output,m)
if err != nil {
panic("encoding fail...")
}
*/
}