Android新姿式:截屏代码整理

 今天作项目要用到android截屏功能,一开始我还庆幸看过一些博客的文章,自信能轻松解决。。。- - 结果坑了一天才搞了个差很少的交差。。。哎!java

关于android截屏的代码,大体有3种方法,有兴趣的看下去吧。linux

方法一:android

/**
     * 根据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 (Exception e) {
            e.printStackTrace();
        }
    }

网上看了不少文章,大多用的是这样的方法,直接把一个View转换成Bitmap,而后保存到sd卡。web

这个方法用起来很简单,saveFile(getViewBitmap(view),filename);一句代码就搞定了。canvas

不过在项目里用上以后坑爹的发现WebView截不了图!!QAQ 好吧,只好无奈的处处找资料。缓存

翻遍百度谷歌找到了这样的代码:测试

/**
     * 截取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的网页不能截图。ui

方法二:spa

截取当前Activity的视图并保存。这个能够说比方法一更简单,只是不够灵活,由于截的图是整个屏幕,但是我又不要状态栏和标题栏。QAQcode

不过若是成功的话,能够把截的图裁剪一下取出本身须要的部分,也是没问题的。惋惜这个方法也不能截出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屏幕截图”

下面说我整理的代码,经测试在个人手机上是能够成功截图的,使用了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 但也已经尽力了,先这样吧!以后会改进的~

相关文章
相关标签/搜索