- 论坛徽章:
- 0
|
我需要在Android的Native代码中进行全屏截图,通过读取framebuffer来获得raw 数据,然后转换成b4bmp并保存为文件。但是为什么我只能得到一张模糊错位的图片,有人知道为什么吗?谢谢!- #include <stdlib.h>
- #include <stdio.h>
- #include <unistd.h>
- #include <fcntl.h>
- #include <sys/mman.h>
- #include <sys/types.h>
- #include <sys/types.h>
- #include <linux/fb.h>
- #pragma pack(1)
- typedef struct bmp_header
- {
- //14B
- unsigned short bfType;
- unsigned int bfSize;
- unsigned short bfReserved1;
- unsigned short bfReserved2;
- unsigned int headersize;
- //40B
- unsigned int infoSize;
- int width;
- int height;
- unsigned short biPlanes;
- unsigned short bits;
- unsigned int biCompression;
- unsigned int biSizeImage;
- int biXPelsPerMeter;
- int biYPelsPerMeter;
- unsigned int biClrUsed;
- unsigned int biClrImportant;
- } BMPHEADER;
- typedef struct {
- unsigned char *bits;
- unsigned size;
- int fd;
- struct fb_fix_screeninfo fi;
- struct fb_var_screeninfo vi;
- } FB;
- static int get_framebuffer(FB *fb)
- {
- fb->fd = open("/dev/graphics/fb0", O_RDWR);
- if(fb->fd < 0) {
- perror("cannot open fb0");
- return -1;
- }
- if(ioctl(fb->fd, FBIOGET_FSCREENINFO, &fb->fi) < 0) {
- perror("failed to get fb0 info");
- return -1;
- }
- if(ioctl(fb->fd, FBIOGET_VSCREENINFO, &fb->vi) < 0) {
- perror("failed to get fb0 info");
- return -1;
- }
- //dumpinfo(&fi, &vi);
- fb->bits = mmap(0, fb->fi.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fb->fd, 0);
- if(fb->bits == MAP_FAILED) {
- perror("failed to mmap framebuffer");
- return -1;
- }
- }
- int fb_bpp(FB *fb)
- {
- if (fb) {
- return fb->vi.bits_per_pixel;
- }
- return 0;
- }
- int fb_width(FB *fb)
- {
- if (fb) {
- return fb->vi.xres;
- }
- return 0;
- }
- int fb_height(FB *fb)
- {
- if (fb) {
- return fb->vi.yres;
- }
- return 0;
- }
- int take_screenshot(char *path)
- {
- int w, h;
- int depth;
- unsigned short *bits;
- FB gr_fb;
- get_framebuffer(&gr_fb);
- w = fb_width(&gr_fb);
- h = fb_height(&gr_fb);
- depth = fb_bpp(&gr_fb);
- //convert pixel data
- uint8_t *rgb24;
- if (depth == 16) {
- rgb24 = (uint8_t *)malloc(w * h * 3);
- int i = 0;
- for ( ; i < w*h; i++) {
- uint16_t pixel16 = ((uint16_t *)gr_fb.bits)[i];
- // RRRRRGGGGGGBBBBBB -> RRRRRRRRGGGGGGGGBBBBBBBB
- // in rgb24 color max is 2^8 per channel (*255/32 *255/64 *255/32)
- rgb24[3*i+0] = (255*(pixel16 & 0x001F))/ 32; //Blue
- rgb24[3*i+1] = (255*((pixel16 & 0x07E0) >> 5))/64; //Green
- rgb24[3*i+2] = (255*((pixel16 & 0xF800) >> 11))/32; //Red
- }
- } else if (depth == 24) {
- rgb24 = (uint8_t *)gr_fb.bits;
- } else if (depth == 32) {
- //skip transparency channel
- rgb24 = (uint8_t *) malloc(w * h * 3);
- int i=0;
- for ( ; i <w*h; i++)
- {
- uint32_t pixel32 = ((uint32_t *)gr_fb.bits)[i];
- // in rgb24 color max is 2^8 per channel
- rgb24[3*i+2] = pixel32 & 0x000000FF; //Blue
- rgb24[3*i+1] = (pixel32 & 0x0000FF00) >> 8; //Green
- rgb24[3*i+0] = (pixel32 & 0x00FF0000) >> 16; //Red
- }
- } else {
- //free
- close(gr_fb.fd);
- exit(2);
- };
- //save RGB 24 Bitmap
- int bytes_per_pixel = 3;
- BMPHEADER bh;
- memset ((char *)&bh,0,sizeof(BMPHEADER)); // sets everything to 0
- //bh.filesize = calculated size of your file (see below)
- //bh.reserved = two zero bytes
- bh.bfType = 0x4D42;
- bh.bfReserved1 = 0;
- bh.bfReserved2 = 0;
- bh.headersize = 54L;
- bh.infoSize = 0x28L; // for 24 bit images
- bh.width = w; // width of image in pixels
- bh.height = -h; // height of image in pixels
- bh.biPlanes = 1; // for 24 bit images
- bh.bits = 8 * bytes_per_pixel; // for 24 bit images
- bh.biCompression = 0L; // no compression
- int bytesPerLine;
- bytesPerLine = w * bytes_per_pixel; // for 24 bit images
- //round up to a dword boundary
- if (bytesPerLine & 0x0003) {
- bytesPerLine |= 0x0003;
- ++bytesPerLine;
- }
- bh.biSizeImage = (long)bytesPerLine * bh.height;
- bh.bfSize = bh.headersize + bh.biSizeImage;
- FILE * bmpfile;
- //printf("Bytes per line : %d\n", bytesPerLine);
- bmpfile = fopen(path, "wb");
- if (bmpfile == NULL) {
- close(gr_fb.fd);
- exit(3);
- }
- fwrite((char *)&bh, 1, sizeof (bh), bmpfile);
- fwrite(rgb24,1,w*h*3,bmpfile);
- fclose(bmpfile);
- close(gr_fb.fd);
- return 0;
- }
复制代码
|
|