为方便以后学习和工作,现转载一批文章,方便以后使用。

来源:http://blog.sina.com.cn/s/blog_4a0a39c30100auh9.html 作者:风子

如对Android原生(Natvie)C开发还任何疑问,请参阅《Android原生(Native)C开发之一:环境搭建篇》:http://blog.sina.com.cn/s/blog_4a0a39c30100auh9.html(或者http://android-sz.iteye.com/blog/828246)

虽然现在能通过交叉环境编译程序,并push到Android上执行,但那只是console台程序,是不是有些单调呢?下面就要看如何通过Linux的 framebuffer 技术在Android上画图形,关于Linux的framebuffer技术,这里就不再详细讲解了,请大家google一下。

操作framebuffer的主要步骤如下:

1、打开一个可用的FrameBuffer设备;
2、通过mmap调用把显卡的物理内存空间映射到用户空间;
3、更改内存空间里的像素数据并显示;

4、退出时关闭framebuffer设备。

下面的这个例子简单地用framebuffer画了一个渐变的进度条,代码 framebuf.c 如下:

#include <unistd.h>#include <stdio.h>#include <fcntl.h>#include <linux/fb.h>#include <sys/mman.h>inline static unsigned short int make16color(unsigned char r, unsigned char g, unsigned char b){    return ( (((r >> 3) & 31) << 11) | (((g >> 2) & 63) << 5)  |  ((b >> 3) & 31)        );}int main() {    int fbfd = 0;    struct fb_var_screeninfo vinfo;    struct fb_fix_screeninfo finfo;    long int screensize = 0; char *fbp = 0;    int x = 0, y = 0;    int guage_height = 20, step = 10;    long int location = 0;    // Open the file for reading and writing    fbfd = open("/dev/graphics/fb0", O_RDWR);    if (!fbfd) {        printf("Error: cannot open framebuffer device.\n");        exit(1);    }    printf("The framebuffer device was opened successfully.\n");    // Get fixed screen information    if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {        printf("Error reading fixed information.\n");        exit(2);    }    // Get variable screen information    if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {        printf("Error reading variable information.\n");        exit(3);    } printf("sizeof(unsigned short) = %d\n", sizeof(unsigned short));    printf("%dx%d, %dbpp\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel ); printf("xoffset:%d, yoffset:%d, line_length: %d\n", vinfo.xoffset, vinfo.yoffset, finfo.line_length );    // Figure out the size of the screen in bytes    screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel / 8;;    // Map the device to memory    fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,                       fbfd, 0);    if ((int)fbp == -1) {        printf("Error: failed to map framebuffer device to memory.\n");        exit(4);    }    printf("The framebuffer device was mapped to memory successfully.\n"); //set to black color first memset(fbp, 0, screensize);    //draw rectangle    y = (vinfo.yres - guage_height) / 2 - 2;       // Where we are going to put the pixel    for (x = step - 2; x < vinfo.xres - step + 2; x++) {        location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                       (y+vinfo.yoffset) * finfo.line_length;        *((unsigned short int*)(fbp + location)) = 255;    }    y = (vinfo.yres + guage_height) / 2 + 2;       // Where we are going to put the pixel    for (x = step - 2; x < vinfo.xres - step + 2; x++) {        location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                       (y+vinfo.yoffset) * finfo.line_length;        *((unsigned short int*)(fbp + location)) = 255;    }    x = step - 2;    for (y = (vinfo.yres - guage_height) / 2 - 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {        location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                       (y+vinfo.yoffset) * finfo.line_length;        *((unsigned short int*)(fbp + location)) = 255;    }    x = vinfo.xres - step + 2;    for (y = (vinfo.yres - guage_height) / 2 - 2; y < (vinfo.yres + guage_height) / 2 + 2; y++) {        location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                       (y+vinfo.yoffset) * finfo.line_length;        *((unsigned short int*)(fbp + location)) = 255;    }    // Figure out where in memory to put the pixel    for ( x = step; x < vinfo.xres - step; x++ ) {        for ( y = (vinfo.yres - guage_height) / 2; y < (vinfo.yres + guage_height) / 2; y++ ) {            location = (x+vinfo.xoffset) * (vinfo.bits_per_pixel/8) +                       (y+vinfo.yoffset) * finfo.line_length;            if ( vinfo.bits_per_pixel == 32 ) {                *(fbp + location) = 100;        // Some blue                *(fbp + location + 1) = 15+(x-100)/2;     // A little green                *(fbp + location + 2) = 200-(y-100)/5;    // A lot of red                *(fbp + location + 3) = 0;      // No transparency            } else { //assume 16bpp                unsigned char b = 255 * x / (vinfo.xres - step);                unsigned char g = 255;     // (x - 100)/6 A little green                unsigned char r = 255;    // A lot of red                unsigned short int t = make16color(r, g, b);                *((unsigned short int*)(fbp + location)) = t;            }        }  //printf("x = %d, temp = %d\n", x, temp);        //sleep to see it        usleep(200);    }    //clean framebuffer    munmap(fbp, screensize);    close(fbfd);    return 0;}

注意,在Android环境,framebuffer设备不是象linux一样的 /dev/fb0,而是/dev/graphics/fb0

fbfd = open("/dev/graphics/fb0", O_RDWR);

打开framebuffer设备,

fbp = (char *)mmap(0, screensize, PROT_READ | PROT_WRITE, MAP_SHARED,
fbfd, 0);

将设备map到一块内存,然后就可以操作这块内存空间来显示你想画的图形了。

最后别忘了关闭设备:

munmap(fbp, screensize);
close(fbfd);

效果图如下:


更多相关文章

  1. Android内核和驱动程序
  2. Android外设存储设备的访问及测试
  3. Android: Android(安卓)Bluetooth
  4. Android简单自定义圆形和水平ProgressBar
  5. Android的源代码结构
  6. Android获取经纬度
  7. 把应用跑在android上
  8. Android练习小项目时踩到的坑
  9. Android(安卓)调试桥

随机推荐

  1. Delphi XE5 for android 调用Java类库必
  2. Android如何实现ListView的Item松开渐变
  3. android java.lang.SecurityException: P
  4. Android客户端与J2EE服务器的互联
  5. Android关于常用正则号码类Util
  6. 我们把 iOS 的 Cocoa Touch 移植到了 And
  7. 基于Android的SIP电话-----Speex 回音消
  8. Android接入微信支付完全解析,太全了~
  9. Android 计算器源码
  10. Android的理解