Android新姿勢:截屏代碼整理

來源:互聯網
上載者:User

標籤:des   android   style   http   io   color   ar   os   使用   

 今天做項目要用到android截屏功能,一開始我還慶幸看過一些部落格的文章,自信能輕鬆解決。。。- - 結果坑了一天才搞了個差不多的交差。。。哎!

關於android截屏的代碼,大致有3種方法,有興趣的看下去吧。

方法一:

網上看了很多文章,大多用的是這樣的方法,直接把一個View轉換成Bitmap,然後儲存到sd卡。

/**

 * 根據view來產生bitmap圖片,可用於功能

 */

public static Bitmap getViewBitmap(View v) {

v.clearFocus(); //

v.setPressed(false); //

// 能畫緩衝就返回false

boolean willNotCache = v.willNotCacheDrawing();

v.setWillNotCacheDrawing(false);

int color = v.getDrawingCacheBackgroundColor();

v.setDrawingCacheBackgroundColor(0);

if (color != 0) {

v.destroyDrawingCache();

}

v.buildDrawingCache();

Bitmap cacheBitmap = v.getDrawingCache();

if (cacheBitmap == null) {

return null;

}

Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);

// Restore the view

v.destroyDrawingCache();

v.setWillNotCacheDrawing(willNotCache);

v.setDrawingCacheBackgroundColor(color);

return bitmap;

}

/**

 * 儲存Bitmap圖片為本地檔案

 */

public static void saveFile(Bitmap bitmap, String filename) {

FileOutputStream fileOutputStream = null;

try {

fileOutputStream = new FileOutputStream(filename);

if (fileOutputStream != null) {

bitmap.compress(Bitmap.CompressFormat.PNG, 90, fileOutputStream);

fileOutputStream.flush();

fileOutputStream.close();

}

} catch (FileNotFoundException e) {

L.d("Exception:FileNotFoundException");

e.printStackTrace();

} catch (IOException e) {

L.d("IOException:IOException");

e.printStackTrace();

}

}

這個方法用起來很簡單,saveFile(getViewBitmap(view),filename);一句代碼就搞定了。

不過在項目裡用上之後坑爹的發現WebView截不了圖!!QAQ 好吧,只好無奈的到處找資料。

翻遍百度Google找到了這樣的代碼:

/**

 * 截取webView可視地區的

 * @param webView 前提:WebView要設定webView.setDrawingCacheEnabled(true);

 * @return

 */

public static Bitmap captureWebViewVisibleSize(WebView webView) {

Bitmap bmp = webView.getDrawingCache();

return bmp;

}

/**

 * 截取webView快照(webView載入的整個內容的大小)

 * @param webView

 * @return

 */

public static Bitmap captureWebView(WebView webView) {

Picture snapShot = webView.capturePicture();

Bitmap bmp = Bitmap.createBitmap(snapShot.getWidth(),

snapShot.getHeight(), Bitmap.Config.ARGB_8888);

Canvas canvas = new Canvas(bmp);

snapShot.draw(canvas);

return bmp;

}

不過還是解決不了我的問題,原因我想應該是我的webview是用了anychart的js檔案和swf檔案來組建圖表的,網上也找到一些人情況跟我一樣,說是用了swf的網頁不能。

方法二:

截取當前Activity的視圖並儲存。這個可以說比方法一更簡單,只是不夠靈活,因為截的圖是整個螢幕,可是我又不要狀態列和標題列。QAQ

不過如果成功的話,可以把截的圖裁剪一下取出自己需要的部分,也是沒問題的。可惜這個方法也不能截出WebView的動態圖表。

代碼給出如下:

/**

 * 截屏

 * @param activity

 * @return

 */

public static Bitmap captureScreen(Activity activity) {

activity.getWindow().getDecorView().setDrawingCacheEnabled(true);

Bitmap bmp=getWindow().getDecorView().getDrawingCache();

return bmp;

}

其實這個方法也算是方法一的延伸,都是用到View的getDrawingCache()方法來擷取Bitmap,所以不行也是理所當然的。

方法三:

第三種方法是用FrameBuffer實現的截屏,這才是真正意義上的!(哎,加班了1個小時,終於讓我找到些眉目了!)

先介紹下FrameBuffer:framebuffer是linux核心對顯示的最底層驅動。在一般的linux檔案系統中,通過/dev/fb0裝置檔案來提供給應用程式對framebuffer進行讀寫的訪問。這裡,如果有多個顯示裝置,就將依次出現fb1,fb2,…等檔案。而在我們所說的android系統中,這個裝置檔案被放在了/dev/graphics/fb0,而且往往只有這一個。

(你看懂了嗎?反正我看不懂。。。)

至於詳細的原理有興趣的可以去百度“FrameBuffer中擷取Android螢幕”

下面說我整理的代碼,經測試在My Phone上是可以成功的,使用了anychart的webview也能截下來。

/**

 * 截屏

 * @param activity

 * @return

 */

public static Bitmap captureScreen(Activity activity) {

// 擷取螢幕大小:

DisplayMetrics metrics = new DisplayMetrics();

WindowManager WM = (WindowManager) activity

.getSystemService(Context.WINDOW_SERVICE);

Display display = WM.getDefaultDisplay();

display.getMetrics(metrics);

int height = metrics.heightPixels; // 螢幕高

int width = metrics.widthPixels; // 螢幕的寬

// 擷取顯示方式

int pixelformat = display.getPixelFormat();

PixelFormat localPixelFormat1 = new PixelFormat();

PixelFormat.getPixelFormatInfo(pixelformat, localPixelFormat1);

int deepth = localPixelFormat1.bytesPerPixel;// 位深

byte[] piex = new byte[height * width * deepth];

try {

Runtime.getRuntime().exec(

new String[] { "/system/bin/su", "-c",

"chmod 777 /dev/graphics/fb0" });

} catch (IOException e) {

e.printStackTrace();

}

try {

// 擷取fb0資料輸入流

InputStream stream = new FileInputStream(new File(

"/dev/graphics/fb0"));

DataInputStream dStream = new DataInputStream(stream);

dStream.readFully(piex);

} catch (Exception e) {

e.printStackTrace();

}

// 儲存圖片

int[] colors = new int[height * width];

for (int m = 0; m < colors.length; m++) {

int r = (piex[m * 4] & 0xFF);

int g = (piex[m * 4 + 1] & 0xFF);

int b = (piex[m * 4 + 2] & 0xFF);

int a = (piex[m * 4 + 3] & 0xFF);

colors[m] = (a << 24) + (r << 16) + (g << 8) + b;

}

// piex產生Bitmap

Bitmap bitmap = Bitmap.createBitmap(colors, width, height,

Bitmap.Config.ARGB_8888);

return bitmap;

}

記得在AndroidManifest.xml加上兩行許可權:

<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />

<uses-permission android:name="android.permission.READ_FRAME_BUFFER" />

還有需要注意的是,手機需要root許可權,沒root過的手機我還沒試過,但估計是不行的。

所以搞了大半天,還是不滿意!又不是每個人的手機都有root許可權。。。QAQ 但也已經儘力了,先這樣吧!之後會改進的~


Android新姿勢:截屏代碼整理

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在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.