Android保存View到本地图片

最近在看Android的系统源码,在看到View的源码的时候,无意间看到了在源码中有这么一个函数:

 /**
     * Create a snapshot of the view into a bitmap.  We should probably make
     * some form of this public, but should think about the API.
     */
    Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
通过注释,我可以知道,这个函数就是用于将View绘制的内容保存到一个Bitmap中进行返回,用户需要的话可以将该

Bitmap保存到任意位置。看到这里,我突然想起来,以前用过网上的保存View到图片的代码,这里先贴上两份代码:

1.网络上的保存代码:

Bitmap bitmap = Bitmap.createBitmap(ivTest.getMeasuredWidth(), ivTest.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas();
        canvas.setBitmap(bitmap);
        ivTest.draw(canvas);
2.View中的createSnapshot中的代码:

代码稍微有点长,但是考虑的方面比较多。所以,效果也比较好,后面会有对比:

/**
     * Create a snapshot of the view into a bitmap.  We should probably make
     * some form of this public, but should think about the API.
     */
    Bitmap createSnapshot(Bitmap.Config quality, int backgroundColor, boolean skipChildren) {
        int width = mRight - mLeft;
        int height = mBottom - mTop;

        final AttachInfo attachInfo = mAttachInfo;
        final float scale = attachInfo != null ? attachInfo.mApplicationScale : 1.0f;
        width = (int) ((width * scale) + 0.5f);
        height = (int) ((height * scale) + 0.5f);

        Bitmap bitmap = Bitmap.createBitmap(mResources.getDisplayMetrics(),
                width > 0 ? width : 1, height > 0 ? height : 1, quality);
        if (bitmap == null) {
            throw new OutOfMemoryError();
        }

        Resources resources = getResources();
        if (resources != null) {
            bitmap.setDensity(resources.getDisplayMetrics().densityDpi);
        }

        Canvas canvas;
        if (attachInfo != null) {
            canvas = attachInfo.mCanvas;
            if (canvas == null) {
                canvas = new Canvas();
            }
            canvas.setBitmap(bitmap);
              .........
            attachInfo.mCanvas = null;
        } else {
            // This case should hopefully never or seldom happen
            canvas = new Canvas(bitmap);
        }

        if ((backgroundColor & 0xff000000) != 0) {     //用于处理背景
            bitmap.eraseColor(backgroundColor);
        }

        .........

        // Fast path for layouts with no backgrounds
        if ((mPrivateFlags & PFLAG_SKIP_DRAW) == PFLAG_SKIP_DRAW) {
            dispatchDraw(canvas);
            if (mOverlay != null && !mOverlay.isEmpty()) {
                mOverlay.getOverlayView().draw(canvas);
            }
        } else {
            draw(canvas);
        }

        mPrivateFlags = flags;

        canvas.restoreToCount(restoreCount);
        canvas.setBitmap(null);

        if (attachInfo != null) {
            // Restore the cached Canvas for our siblings
            attachInfo.mCanvas = canvas;
        }

        return bitmap;
    }

通过对比,可以看出,两个代码的实现思路相似,createSnapshot中的代码对背景使用eraseColor进行了处理。

同时,看到这里,我发现,在注释中也没有API的限制,同时,官方也有意将改API暴漏出来,想着练练手的目的,我想着用反射看看能不能调用到这个函数呢?答案肯定是可以的,下面直接上我的代码:

private void saveViewUserInvoke(){
        Class cls = ivTest.getClass();
        while (!cls.getName().equals("android.view.View")){
            cls = cls.getSuperclass();
        }

        try {
            Method method = cls.getDeclaredMethod("createSnapshot", new Class[]{Bitmap.Config.class, int.class, boolean.class});
            method.setAccessible(true);
            Bitmap bitmap = (Bitmap) method.invoke(ivTest, Bitmap.Config.ARGB_8888, Color.WHITE, false);
            saveBitmapToFile(bitmap);  //自定义的保存函数
        } catch (Exception e) {
            e.printStackTrace();
        }

    }
这样就可以简单的,并且完美的保存图片到本地了。下面贴上效果图:右边是保存后的效果。



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值