在android上面做螢幕需要經過兩個步驟
1.從framebuffer擷取RGB的原始位元組(大小是 寬*高*映像深度/8)
int fbfd = 0;
struct fb_var_screeninfo vinfo;//儲存這framebuffer的各自資料,寬高等等
fbfd = open("/dev/graphics/fb0", O_RDWR);
if (!fbfd) {
printf("Error: cannot open framebuffer device.\n");
return 0;
}
if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
printf("Error: reading variable information.\n");
return 0;
}
screensize = vinfo.xres * vinfo.yres * vinfo.bits_per_pixel >> 3;
fbp = (char *) mmap(0, screensize, PROT_READ, MAP_SHARED, fbfd, 0);
uint8_t rgv_24[screensize];
memcpy(rgv_24, fbp, screensize);
這樣rgv_24中就是我們得到的RGB原始位元組了,接下來的就是執行第兒個步驟了
2.將原始位元組轉成JPEG或者PNG等等壓縮後的可以直接看的圖
第一種方法:
在RGB原始位元組的最前面加上BMP位元影像的54個描述位元組,即可成一張完成的BMP位元影像
第二種方法:
將RGB原始位元組資料回傳到java中使用Bitmap轉換成圖片
第三種方法就是在C中直接調用Android SkImageEncoder等介面轉成圖片,不過要注意的是在SkBitMap中不支援RGB24的位元影像,因此需要轉換成RGB565才能往下走。
SkBitmap mSkBitmap;
mSkBitmap.setConfig(SkBitmap::kRGB_565_Config, vinfo.xres, vinfo.yres);
mSkBitmap.setPixels(rgv_16);
SkDynamicMemoryWStream stream;//圖片流,其實就是圖片內容
SkImageEncoder::EncodeStream(&stream, mSkBitmap, SkImageEncoder::kJPEG_Type,100);
int fd = open(ssPath, O_WRONLY | O_CREAT); //開啟檔案
int size = stream.getOffset();//這個是圖片的大小
write(fd, stream.getStream(), size);//儲存到圖片
close(fd);
附:
static void rgb24_to_rgb565(long rgb24_size, uint8_t *rgb24, uint8_t *rgb16) {
int i = 0, j = 0;
for (i = 0; i < rgb24_size; i += 3) {
rgb16[j] = rgb24[i] >> 3; // B
rgb16[j] |= ((rgb24[i + 1] & 0x1C) << 3); // G
rgb16[j + 1] = rgb24[i + 2] & 0xF8; // R
rgb16[j + 1] |= (rgb24[i + 1] >> 5); // G
j += 2;
}
}