Android中view转换为bitmap为null解决方案

前言

我们经常会用到将一个View转换为Bitmap的情景,比如截屏保存到本地,比如一些动态的实时View为便于观察和记录数据、需要临时生成静态的Bitmap等等。
我们一般都会这样写:

public static Bitmap convertViewToBitmap(View view){
       view.buildDrawingCache();
    Bitmap bitmap = view.getDrawingCache();
    return bitmap; 
}

一般情况这种是没有问题的,但是view过大的话,就会buildDrawingCache()失败,当然我们getDrawingCache()得到的bitmap就为null了!

原因

那么为什么会出现这种情况呢?我们可以从源码中看到:
buildDrawingCache(boolean autoScale)
---->buildDrawingCacheImpl(boolean autoScale)

final boolean opaque = drawingCacheBackgroundColor != 0 || isOpaque();
final boolean use32BitCache = attachInfo != null && attachInfo.mUse32BitDrawingCache;

final long projectedBitmapSize = width * height * (opaque && !use32BitCache ? 2 : 4);
final long drawingCacheSize =ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize();
if (width <= 0 || height <= 0 || projectedBitmapSize > drawingCacheSize) {
	if (width > 0 && height > 0) {
		Log.w(VIEW_LOG_TAG, getClass().getSimpleName() + " not displayed because it is"
                        + " too large to fit into a software layer (or drawing cache), needs "
                        + projectedBitmapSize + " bytes, only "
                        + drawingCacheSize + " available");
	}
	destroyDrawingCache();
	mCachingFailed = true;
	return;
}

widthheight是所要cache的view绘制的宽度和高度,所以(width * height * (opaque && !use32BitCache ? 2 : 4)
计算的是当前所需要的cache大小。
ViewConfiguration.get(mContext).getScaledMaximumDrawingCacheSize()得到的是系统所提供的最大的DrawingCache的值
当所需要的```drawingCache`` >系统所提供的最大DrawingCache值时,生成Bitmap就会出现问题,此时获取的Bitmap就为null。

解决方案

我在stackoverflow上面找到一个类似的回答:
Android View.getDrawingCache returns null, only null
所以,我们应该这样写:

public static Bitmap convertViewToBitmap(View view){
	view.setDrawingCacheEnabled(true);
	view.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
	view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
	view.buildDrawingCache();
	Bitmap bitmap = view.getDrawingCache();
	view.setDrawingCacheEnabled(false);  
	return bitmap;    
}

替代方案

从源码中可以看到buildDrawingCache过程貌似就是利用获得View的Canvas然后画到bitmap上,直接返回对应的bitmap,这样一来,就是我们用getDrawingCache获得的bitmap;跟我们直接将View画到bitmap区别不是很大,所以我们可以自己直接画:

public static Bitmap convertViewToBitmap(View view) {  
	Bitmap bitmap= Bitmap.createBitmap(view.getWidth(), view.getHeight(), HDConstantSet.BITMAP_QUALITY);  
	Canvas canvas = new Canvas(bitmap);  
	view.draw(canvas);  
	return bitmap;  
}

另外可能要这样的问题:就是在滑动的view中这样操作的话会产生问题,具体的可以参照这篇博客:
View的getDrawingCache为空,解决办法

ScrollView转bitmap

这里我们使用直接绘制的办法:

    public Bitmap scrollToBitmap(ScrollView scrollView) {
        int h = 0;
        Bitmap bitmap;
        for (int i = 0; i < scrollView.getChildCount(); i++) {
            h += scrollView.getChildAt(i).getHeight();
        }
        bitmap = Bitmap.createBitmap(scrollView.getWidth(), h, Bitmap.Config.RGB_565);
        Canvas canvas = new Canvas(bitmap);
        canvas.drawColor(Color.WHITE);
        scrollView.draw(canvas);
        return bitmap;
    }

参考文章:
Android中View转换为Bitmap及getDrawingCache=null的解决方法

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值