我需要得到一个View
的屏幕截图。我已经尝试了两种方法来完成这项工作。不幸的是,两种方法都导致了同样的bug。
以下是日志:
java.lang.IllegalArgumentException: Software rendering doesn't support hardware bitmaps
at android.graphics.BaseCanvas.null onHwBitmapInSwMode(null)(BaseCanvas.java:550)
at android.graphics.BaseCanvas.null throwIfHwBitmapInSwMode(null)(BaseCanvas.java:557)
at android.graphics.BaseCanvas.null throwIfCannotDraw(null)(BaseCanvas.java:69)
at android.graphics.BaseCanvas.null drawBitmap(null)(BaseCanvas.java:127)
at android.graphics.Canvas.null drawBitmap(null)(Canvas.java:1504)
at android.graphics.drawable.BitmapDrawable.null draw(null)(BitmapDrawable.java:545)
at android.widget.ImageView.null onDraw(null)(ImageView.java:1355)
at android.view.View.null draw(null)(View.java:20248)
at android.view.View.null draw(null)(View.java:20118)
at android.view.ViewGroup.null drawChild(null)(ViewGroup.java:4336)
at android.view.ViewGroup.null dispatchDraw(null)(ViewGroup.java:4115)
at android.view.ViewOverlay$OverlayViewGroup.null dispatchDraw(null)(ViewOverlay.java:251)
at android.view.View.null draw(null)(View.java:20251)
at android.view.View.null buildDrawingCacheImpl(null)(View.java:19516)
at android.view.View.null buildDrawingCache(null)(View.java:19379)
at android.view.View.null getDrawingCache(null)(View.java:19215)
at android.view.View.null getDrawingCache(null)(View.java:19166)
at com.omnipotent.free.videodownloader.pro.utils.ViewUtils.android.graphics.Bitmap captureView(android.view.View)(ViewUtils.java:70)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity.com.omnipotent.free.videodownloader.pro.data.bean.TabBean getCurrentTabsData()(MainActivity.java:325)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity.com.omnipotent.free.videodownloader.pro.data.bean.TabBean access$getCurrentTabsData(com.omnipotent.free.videodownloader.pro.ui.main.MainActivity)(MainActivity.java:84)
at com.omnipotent.free.videodownloader.pro.ui.main.MainActivity$onAddTab$1.void run()(MainActivity.java:628)
at android.os.Handler.null handleCallback(null)(Handler.java:873)
at android.os.Handler.null dispatchMessage(null)(Handler.java:99)
at android.os.Looper.null loop(null)(Looper.java:193)
at android.app.ActivityThread.null main(null)(ActivityThread.java:6936)
at java.lang.reflect.Method.null invoke(null)(Method.java)
at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.null run(null)(RuntimeInit.java:493)
at com.android.internal.os.ZygoteInit.null main(null)(ZygoteInit.java:870)
我已经仔细检查了代码,并在网上查找了相关文章,但我仍然没有解决它,这真的让我感到沮丧,这个bug只发生在android O之上。
以下是我尝试过的两种方法:
方法一:
public static Bitmap captureView(View view) {
Bitmap tBitmap = Bitmap.createBitmap(
view.getWidth(), view.getHeight(), Bitmap.Config.RGB_565);
Canvas canvas = new Canvas(tBitmap);
view.draw(canvas);
canvas.setBitmap(null);
return tBitmap;
}
方法二:
public static Bitmap captureView(View view) {
if (view == null) return null;
boolean drawingCacheEnabled = view.isDrawingCacheEnabled();
boolean willNotCacheDrawing = view.willNotCacheDrawing();
view.setDrawingCacheEnabled(true);
view.setWillNotCacheDrawing(false);
final Bitmap drawingCache = view.getDrawingCache();
Bitmap bitmap;
if (null == drawingCache) {
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.createBitmap(view.getDrawingCache());
} else {
bitmap = Bitmap.createBitmap(drawingCache);
}
view.destroyDrawingCache();
view.setWillNotCacheDrawing(willNotCacheDrawing);
view.setDrawingCacheEnabled(drawingCacheEnabled);
return bitmap;
}
需要提到的是,我已经为我的Activity
设置了android:hardwareAccelerated="true"
,在那里我调用了captureView
方法。
7条答案
按热度按时间zaqlnxep1#
读取Glide hardware bitmap docs,并找到
PixelCopy
类,这可能会解决这个bug。在Android O上使用
PixelCopy
将view
转换为Bitmap
,在Android O下使用之前的方法。下面是我的代码:
不足之处在于我必须使用回调,我不太喜欢回调。
希望能成功。
guz6ccqo2#
你可以尝试复制硬件类型位图到你想要的类型位图,例如:
xwmevbvl3#
基于@wang willway的回复,我创建了这个View的Kotlin扩展。
在合成中将其用作:
dnph8jn44#
如果您正在转换一个包含ImageView的视图,并且您正在使用图像加载库(如Glide或coil)加载其图像,则必须禁用硬件位图。这些库仅在图形内存中存储像素数据,并且最适合位图仅绘制到屏幕的情况。
如果你使用线圈,那么你必须这样做
r7s23pms5#
我用它来截屏可组合对象,但是你可以不用Composes来使用它。它返回你可能会计数为
ImageResult
内的 Package 错误的每一个异常。有趣的视图。屏幕截图(位图回调:(图像结果)-〉单位){
}
用途
idfiyjo86#
这可能会帮助某人在未来在我的情况下,这是由于给固定高度的评级栏,并在同一时间设置风格如下
第一个月
对我起作用的只是 Package 它的高度,而不是给它固定的大小。
b1zrtrql7#
使用此选项捕获视图(适用于Android 8.0):