免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3153 | 回复: 7
打印 上一主题 下一主题

[Android] 为何不能在Android的Native代码中获得截屏? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2013-09-26 12:03 |只看该作者 |倒序浏览
我需要在Android的Native代码中进行全屏截图,通过读取framebuffer来获得raw 数据,然后转换成b4bmp并保存为文件。但是为什么我只能得到一张模糊错位的图片,有人知道为什么吗?谢谢!
  1. #include <stdlib.h>
  2. #include <stdio.h>
  3. #include <unistd.h>
  4. #include <fcntl.h>
  5. #include <sys/mman.h>
  6. #include <sys/types.h>

  7. #include <sys/types.h>
  8. #include <linux/fb.h>

  9. #pragma pack(1)

  10. typedef struct bmp_header
  11. {
  12.     //14B
  13.     unsigned short bfType;
  14.     unsigned int bfSize;
  15.     unsigned short bfReserved1;
  16.     unsigned short bfReserved2;
  17.     unsigned int headersize;

  18.     //40B
  19.     unsigned int infoSize;
  20.     int width;
  21.     int height;
  22.     unsigned short biPlanes;
  23.     unsigned short bits;
  24.     unsigned int biCompression;
  25.     unsigned int biSizeImage;
  26.     int biXPelsPerMeter;
  27.     int biYPelsPerMeter;
  28.     unsigned int biClrUsed;
  29.     unsigned int biClrImportant;

  30. } BMPHEADER;


  31. typedef struct {
  32.     unsigned char *bits;
  33.     unsigned size;
  34.     int fd;
  35.     struct fb_fix_screeninfo fi;
  36.     struct fb_var_screeninfo vi;
  37. } FB;

  38. static int get_framebuffer(FB *fb)
  39. {
  40.     fb->fd = open("/dev/graphics/fb0", O_RDWR);
  41.     if(fb->fd < 0) {
  42.         perror("cannot open fb0");
  43.         return -1;
  44.     }

  45.     if(ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->fi) < 0) {
  46.         perror("failed to get fb0 info");
  47.         return -1;
  48.     }

  49.     if(ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0) {
  50.         perror("failed to get fb0 info");
  51.         return -1;
  52.     }

  53.     //dumpinfo(&fi, &vi);
  54.     fb->bits = mmap(0, fb->fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0);
  55.     if(fb->bits == MAP_FAILED) {
  56.         perror("failed to mmap framebuffer");
  57.         return -1;
  58.     }

  59. }

  60. int fb_bpp(FB *fb)
  61. {
  62.     if (fb) {
  63.         return fb->vi.bits_per_pixel;
  64.     }
  65.     return 0;
  66. }

  67. int fb_width(FB *fb)
  68. {
  69.     if (fb) {
  70.         return fb->vi.xres;
  71.     }
  72.     return 0;
  73. }

  74. int fb_height(FB *fb)
  75. {
  76.     if (fb) {
  77.         return fb->vi.yres;
  78.     }
  79.     return 0;
  80. }

  81. int take_screenshot(char *path)
  82. {
  83.     int w, h;
  84.     int depth;
  85.     unsigned short *bits;
  86.     FB gr_fb;

  87.     get_framebuffer(&gr_fb);

  88.     w = fb_width(&gr_fb);
  89.     h = fb_height(&gr_fb);
  90.     depth = fb_bpp(&gr_fb);

  91.     //convert pixel data
  92.     uint8_t *rgb24;
  93.     if (depth == 16) {
  94.         rgb24 = (uint8_t *)malloc(w * h * 3);
  95.         int i = 0;
  96.         for ( ; i < w*h; i++) {
  97.             uint16_t pixel16 = ((uint16_t *)gr_fb.bits)[i];
  98.             // RRRRRGGGGGGBBBBBB -> RRRRRRRRGGGGGGGGBBBBBBBB
  99.             // in rgb24 color max is 2^8 per channel (*255/32 *255/64 *255/32)
  100.             rgb24[3*i+0]   = (255*(pixel16 & 0x001F))/ 32;      //Blue
  101.             rgb24[3*i+1]   = (255*((pixel16 & 0x07E0) >> 5))/64;    //Green
  102.             rgb24[3*i+2]     = (255*((pixel16 & 0xF800) >> 11))/32;     //Red
  103.         }
  104.     } else if (depth == 24) {
  105.         rgb24 = (uint8_t *)gr_fb.bits;
  106.     } else if (depth == 32) {
  107.         //skip transparency channel
  108.         rgb24 = (uint8_t *) malloc(w * h * 3);
  109.         int i=0;
  110.         for ( ; i <w*h; i++)
  111.         {
  112.             uint32_t pixel32 = ((uint32_t *)gr_fb.bits)[i];
  113.             // in rgb24 color max is 2^8 per channel
  114.             rgb24[3*i+2]   =  pixel32 & 0x000000FF;         //Blue
  115.             rgb24[3*i+1]   = (pixel32 & 0x0000FF00) >> 8;   //Green
  116.             rgb24[3*i+0]   = (pixel32 & 0x00FF0000) >> 16;  //Red
  117.         }
  118.     } else {
  119.         //free
  120.         close(gr_fb.fd);
  121.         exit(2);
  122.     };


  123.     //save RGB 24 Bitmap
  124.     int bytes_per_pixel = 3;
  125.     BMPHEADER bh;
  126.     memset ((char *)&bh,0,sizeof(BMPHEADER)); // sets everything to 0
  127.     //bh.filesize  =   calculated size of your file (see below)
  128.     //bh.reserved  = two zero bytes
  129.     bh.bfType = 0x4D42;
  130.     bh.bfReserved1 = 0;
  131.     bh.bfReserved2 = 0;
  132.     bh.headersize = 54L;
  133.     bh.infoSize  =  0x28L;      // for 24 bit images
  134.     bh.width     = w;           // width of image in pixels
  135.     bh.height    = -h;          // height of image in pixels
  136.     bh.biPlanes  = 1;           // for 24 bit images
  137.     bh.bits      = 8 * bytes_per_pixel; // for 24 bit images
  138.     bh.biCompression = 0L;      // no compression
  139.     int bytesPerLine;
  140.     bytesPerLine = w * bytes_per_pixel;     // for 24 bit images
  141.     //round up to a dword boundary
  142.     if (bytesPerLine & 0x0003) {
  143.         bytesPerLine |= 0x0003;
  144.         ++bytesPerLine;
  145.     }
  146.     bh.biSizeImage = (long)bytesPerLine * bh.height;
  147.     bh.bfSize = bh.headersize + bh.biSizeImage;
  148.     FILE * bmpfile;
  149.     //printf("Bytes per line : %d\n", bytesPerLine);
  150.     bmpfile = fopen(path, "wb");
  151.     if (bmpfile == NULL) {
  152.         close(gr_fb.fd);
  153.         exit(3);
  154.     }
  155.     fwrite((char *)&bh, 1, sizeof (bh), bmpfile);
  156.     fwrite(rgb24,1,w*h*3,bmpfile);

  157.     fclose(bmpfile);
  158.     close(gr_fb.fd);

  159.     return 0;
  160. }
复制代码

论坛徽章:
39
白银圣斗士
日期:2015-11-24 10:40:40酉鸡
日期:2015-03-20 14:15:44寅虎
日期:2015-03-20 14:13:59午马
日期:2015-03-20 14:13:16白羊座
日期:2015-03-20 14:12:54金牛座
日期:2015-03-20 14:12:09双子座
日期:2015-03-20 14:11:57巨蟹座
日期:2015-03-20 14:11:44狮子座
日期:2015-03-20 14:11:29亥猪
日期:2015-03-20 14:16:24戌狗
日期:2015-03-20 14:16:40申猴
日期:2015-03-20 14:17:05
2 [报告]
发表于 2013-09-26 16:20 |只看该作者
我测试了两台手机,一台截屏经常是黑色的,另一台正常.

论坛徽章:
39
白银圣斗士
日期:2015-11-24 10:40:40酉鸡
日期:2015-03-20 14:15:44寅虎
日期:2015-03-20 14:13:59午马
日期:2015-03-20 14:13:16白羊座
日期:2015-03-20 14:12:54金牛座
日期:2015-03-20 14:12:09双子座
日期:2015-03-20 14:11:57巨蟹座
日期:2015-03-20 14:11:44狮子座
日期:2015-03-20 14:11:29亥猪
日期:2015-03-20 14:16:24戌狗
日期:2015-03-20 14:16:40申猴
日期:2015-03-20 14:17:05
3 [报告]
发表于 2013-09-26 16:25 |只看该作者
又测试了一台,也是正常的

论坛徽章:
0
4 [报告]
发表于 2013-09-26 17:12 |只看该作者
回复 3# rover12421 从网上找过各种代码实验,都没有成功,多数都是这样模糊错位的。


   

论坛徽章:
39
白银圣斗士
日期:2015-11-24 10:40:40酉鸡
日期:2015-03-20 14:15:44寅虎
日期:2015-03-20 14:13:59午马
日期:2015-03-20 14:13:16白羊座
日期:2015-03-20 14:12:54金牛座
日期:2015-03-20 14:12:09双子座
日期:2015-03-20 14:11:57巨蟹座
日期:2015-03-20 14:11:44狮子座
日期:2015-03-20 14:11:29亥猪
日期:2015-03-20 14:16:24戌狗
日期:2015-03-20 14:16:40申猴
日期:2015-03-20 14:17:05
5 [报告]
发表于 2013-09-26 17:26 |只看该作者
回复 4# sugelawa


    奇怪,我测试了3台手机都没问题哦.

    你用我编译的试试看.执行之后,会在同级目录生成一个screenshot.bmp文件

    screenshot.zip (5.31 KB, 下载次数: 23)

论坛徽章:
0
6 [报告]
发表于 2013-10-03 15:17 |只看该作者
回复 5# rover12421   不好意思,最近出去了几天。你编译的我运行不了,放到Android上运行时提示无权限,但已经是root并且加执行权限了,我重新用那个代码编译并在另一台机器上测试,这次不错位,而是颜色偏差,全部成黄色。


   

论坛徽章:
39
白银圣斗士
日期:2015-11-24 10:40:40酉鸡
日期:2015-03-20 14:15:44寅虎
日期:2015-03-20 14:13:59午马
日期:2015-03-20 14:13:16白羊座
日期:2015-03-20 14:12:54金牛座
日期:2015-03-20 14:12:09双子座
日期:2015-03-20 14:11:57巨蟹座
日期:2015-03-20 14:11:44狮子座
日期:2015-03-20 14:11:29亥猪
日期:2015-03-20 14:16:24戌狗
日期:2015-03-20 14:16:40申猴
日期:2015-03-20 14:17:05
7 [报告]
发表于 2013-10-03 23:39 |只看该作者
回复 6# sugelawa


    这个程序把色彩深度都转成了24位的,所以色彩失真很厉害.
    具体为啥有些机器截出的图片不正常就不太清楚了

论坛徽章:
0
8 [报告]
发表于 2013-10-07 12:46 |只看该作者
回复 7# rover12421 但是截屏保存为32位的那个alpha值没有意义吧?


   
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP