Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> 編程實現Android模擬器中窗口截圖存成文件

編程實現Android模擬器中窗口截圖存成文件

編輯:關於Android編程

Android模擬器內容是用OpenGL渲染的,所以用一般的編程截圖(如PrintWindow()等)會是黑屏。這是因為畫的東西放在framebuffer裡。   一種方法是通過adb把guest的framebuffer數據/dev/graphics/fb0倒到host,再轉為圖片。但這樣速度比較慢。   好在Android模擬器中把guest的framebuffer傳到host進行顯示,所以在host端只要將framebuffer輸出到文件即可。   首先定義每次framebuffer更新時的回調函數:     [cpp]   void zjin_fb_update(void* context,                                 int w, int h, int ydir,                                 int format, int type,                                 unsigned char* pixels)   {   #define CHANNEL 4           BITMAPFILEHEADER bf;       BITMAPINFOHEADER bi;       int width = w;       int height = h;       FILE *file = fopen("capture.bmp", "wb");          if( file!=NULL )       {           memset( &bf, 0, sizeof( bf ) );           memset( &bi, 0, sizeof( bi ) );              bf.bfType = 'MB';//BM?            bf.bfSize = sizeof(bf)+sizeof(bi)+width*height*CHANNEL;           bf.bfOffBits = sizeof(bf)+sizeof(bi);           bi.biSize = sizeof(bi);           bi.biWidth = width;           bi.biHeight = height;           bi.biPlanes = 1;           bi.biBitCount = 8 * CHANNEL;           bi.biSizeImage = width*height*CHANNEL;              fwrite( &bf, sizeof(bf), 1, file );           fwrite( &bi, sizeof(bi), 1, file );           fwrite( pixels, sizeof(unsigned char), height*width*CHANNEL, file );              fclose( file );       }          return;   }     void zjin_fb_update(void* context,                               int w, int h, int ydir,                               int format, int type,                               unsigned char* pixels) { #define CHANNEL 4        BITMAPFILEHEADER bf;     BITMAPINFOHEADER bi;     int width = w;     int height = h;     FILE *file = fopen("capture.bmp", "wb");       if( file!=NULL )     {         memset( &bf, 0, sizeof( bf ) );         memset( &bi, 0, sizeof( bi ) );           bf.bfType = 'MB';//BM?         bf.bfSize = sizeof(bf)+sizeof(bi)+width*height*CHANNEL;         bf.bfOffBits = sizeof(bf)+sizeof(bi);         bi.biSize = sizeof(bi);         bi.biWidth = width;         bi.biHeight = height;         bi.biPlanes = 1;         bi.biBitCount = 8 * CHANNEL;         bi.biSizeImage = width*height*CHANNEL;           fwrite( &bf, sizeof(bf), 1, file );         fwrite( &bi, sizeof(bi), 1, file );         fwrite( pixels, sizeof(unsigned char), height*width*CHANNEL, file );           fclose( file );     }       return; } 然後把這個回調函數注冊上去,比如在OpenGL窗口顯示之後:      [cpp]  android_showOpenglesWindow(winhandle, drect.pos.x, drect.pos.y,                              drect.size.w, drect.size.h, disp->rotation * -90.);   android_setPostCallback(zjin_fb_update, NULL);             android_showOpenglesWindow(winhandle, drect.pos.x, drect.pos.y,                                    drect.size.w, drect.size.h, disp->rotation * -90.);         android_setPostCallback(zjin_fb_update, NULL);這樣,每次有framebuffer的更新時,guest的屏幕都會存成一張bmp圖片,這和用/dev/graphics/fb0的效果是一樣的。    注意用以上方法截下來的圖和原圖有兩點不同,一是Blue和Red通道互換,這是因為framebuffer是RGB,bmp格式裡是BGR。還有就是y軸的零點是左下角,這是由於framebuffer中是OpenGL的坐標系。也就是說,要得到原圖還要經過RGB到BGR的轉換和y-inversion。建議到處理圖片時再做這些處理,一方面不會拖慢模擬器速度,另一方面像OpenCV裡有現成的函數可供調用。    
  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved