Go语言实现AndroidFramebuffer屏幕截图功能

原创
2013/06/24 08:36
阅读数 2.7K
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()), 0, 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, 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...")
    }
    */
}
展开阅读全文
加载中

作者的其它热门文章

打赏
0
7 收藏
分享
打赏
3 评论
7 收藏
0
分享
返回顶部
顶部