編程實現Android模擬器中視窗截圖存成檔案

來源:互聯網
上載者:User

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裡有現成的函數可供調用。  

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.