View或Layout快照保存、截屏功能

来源:互联网 发布:电脑看书软件 编辑:程序博客网 时间:2024/05/16 23:02

初始情形

需要将图片、文字等信息进行组合拼接,生成一张新的图片保存。即,保存View或Layout的快照。特殊情况Webview特殊处理,见文末。

具体实现

主界面

模版一:gone状态
模版二:正常状态
模版三:WebView
.
主界面

第一种 Draw方式

  1. 测量出布局的的宽高
  2. 根据宽高使用Bitmap.createBitmap()方法创建
  3. 通过指定的bitmap创建画布对象
  4. 手动渲染整个布局(包含自布局)到画布对象
  5. 返回bitmap对象,包含这个布局的渲染
    /**     * 从View获取Bitmap  使用Draw方式     */    private Bitmap GetBitmapFromViewDraw(View view){        // 1.获取view宽高        view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),                View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));        int height = view.getMeasuredHeight();        int width = view.getMeasuredWidth();        // 2.创建bitmap        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);        // 3.创建画布对象        Canvas canvas = new Canvas(bitmap);        // 4.手动渲染View到指定的Canvas对象        view.draw(canvas);        // 5. 返回bitmap        return bitmap;    }

分别结果:
模版一 黑屏
.
模版二
.
模版三 全部效果
.
.
此方式特点
1. 但不能将设置为visibility=”gone”的View获取到。
2. 获取的快照大小等固定为模版展示的大小,可能会导致图片位置偏失。
3. 能够获取整个webView的快照

第二种 Cache方式

  1. 设置View开启缓存
  2. 创建缓存bitmap
  3. 获取并拷贝bitmap
  4. 关闭缓存
  5. 返回bitmap对象
    /**     * 从View获得Bitmap  使用Cache方式     */    private Bitmap GetBitmapFromViewCache(View view){        // 重新测量一次  适用于 visibility="gone"        if (View.GONE == view.getVisibility()) {            view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),                    View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));            int height = view.getMeasuredHeight();            int width = view.getMeasuredWidth();            int widthSpec = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);            int heightSpec = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);            view.measure(widthSpec, heightSpec);            view.layout(0, 0, width, height);        }        // 1.缓存view        view.setDrawingCacheEnabled(true);        // 2.启用DrawingCache并创建位图        view.buildDrawingCache();        // 3.获取view缓存        Bitmap bitmap = view.getDrawingCache(true);        // 3.拷贝出来        bitmap = Bitmap.createBitmap(bitmap);        // 4.清除缓存        view.setDrawingCacheEnabled(false);        return bitmap;    }

.
此方式特点
1. 能将设置为visibility=”gone”的View获取到。
2. 获取的快照大小为xml设置中最大值,例如wrap会充满宽度。
3. 不能够获取webView可见范围外的内容。
.
分别结果:
模版一
.
模版二
.
模版三 仅可见部分
.
.

推荐使用第一种方式

WebView不可见范围白屏问题

WebView针对5.0版本的应用程序有一个新的默认行为,减少了内存占用,提高性能通过明智地选择HTML文档的部分需要。但是这里我们需要使用onDraw()做自己的绘画同时访问的可视页面的方式以外的部分页面。

调用如下代码取消优化:

        // 取消 5.0 对WebView的优化        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP) {            WebView.enableSlowWholeDocumentDraw();        }

白屏效果:
白屏 不可见部分
.

最后跟上保存bitmap到本地的方法

    /**     * 将bitmap转成图片文件,并保存在文件夹中     */    public static File saveBitmap(Context context, Bitmap bitmap, String name) throws Exception {        if (bitmap == null || context == null || TextUtils.isEmpty(name)) return null;        FileOutputStream fop;        File file = new File(Environment.getExternalStorageDirectory(), "测试图库");        if (!file.exists()) {            if (!file.mkdirs()) {                return null;            }        }        File image = new File(file, name + ".jpg");        fop = new FileOutputStream(image.getPath());        bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fop);        fop.close();//        // 其次把文件插入到系统图库 选择使用//        MediaStore.Images.Media.insertImage(context.getContentResolver(),//                image.getAbsolutePath(), name + ".jpg", null);//        // 最后通知图库更新//        context.sendBroadcast(new Intent(Intent.ACTION_MEDIA_SCANNER_SCAN_FILE,//                Uri.parse("file:" + File.separator + File.separator + image.getPath())));        return image;    }

GitHub:图片快照截屏小demo;

1 0
原创粉丝点击