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

初始情形

需要将图片、文字等信息进行组合拼接,生成一张新的图片保存。
即,保存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()做自己的绘画同时访问的可视页面的方式以外的部分页面。

调用如下代码取消优化(调用在setContentView()之前):

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

同时还需要设置webView一个属性

<WebView
        android:id="@+id/webview_template"
        android:scrollbars="vertical"
        android:layerType="software"
        android:layout_width="match_parent"
        android:layout_height="match_parent"/>

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

最后跟上保存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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值