我們知道,DDMS可以很容易的擷取
Android手機的螢幕,那麼它是怎麼做到的呢? 其實,android手機上有一個叫做FrameBuffer的裝置,映像資訊都是通過FrameBuffer寫到手機螢幕上去的。因此可以通過讀取此裝置中的資料來擷取當前正在顯示的映像。當然DDMS也是這麼做到的。FrameBuffer對應的裝置檔案就是/dev/graphics/fb0。因此我們可以通過下面的代碼讀取螢幕映像資料。其中傳入的參數fd為一個檔案描述符,也可以是socket描述符。這樣我們就可以把從fb中讀取的螢幕映像資訊傳遞給我們自己的應用,從而擷取手機螢幕資訊。void framebuffer_service(int fd){ struct fb_var_screeninfo vinfo; int fb, offset; char x[256]; struct fbinfo fbinfo; unsigned i, bytespp; fb = open("/dev/graphics/fb0", O_RDONLY); if(fb < 0) goto done; if(ioctl(fb, FBIOGET_VSCREENINFO, &vinfo) < 0) goto done; fcntl(fb, F_SETFD, FD_CLOEXEC); bytespp = vinfo.bits_per_pixel / 8; fbinfo.version = DDMS_RAWIMAGE_VERSION; fbinfo.bpp = vinfo.bits_per_pixel; fbinfo.size = vinfo.xres * vinfo.yres * bytespp; fbinfo.width = vinfo.xres; fbinfo.height = vinfo.yres; fbinfo.red_offset = vinfo.red.offset; fbinfo.red_length = vinfo.red.length; fbinfo.green_offset = vinfo.green.offset; fbinfo.green_length = vinfo.green.length; fbinfo.blue_offset = vinfo.blue.offset; fbinfo.blue_length = vinfo.blue.length; fbinfo.alpha_offset = vinfo.transp.offset; fbinfo.alpha_length = vinfo.transp.length; /* HACK: for several of our 3d cores a specific alignment * is required so the start of the fb may not be an integer number of lines * from the base. As a result we are storing the additional offset in * xoffset. This is not the correct usage for xoffset, it should be added * to each line, not just once at the beginning */ offset = vinfo.xoffset * bytespp; offset += vinfo.xres * vinfo.yoffset * bytespp; printf("offset %d/n", offset); if(writex(fd, &fbinfo, sizeof(fbinfo))) goto done; lseek(fb, offset, SEEK_SET); for(i = 0; i < fbinfo.size; i += 256) { if(readx(fb, &x, 256)) goto done; if(writex(fd, &x, 256)) goto done; } if(readx(fb, &x, fbinfo.size % 256)) goto done; if(writex(fd, &x, fbinfo.size % 256)) goto done;done: if(fb >= 0) close(fb); close(fd);}