从Android视图中捕获位图

10

我之前发布了同样的问题,但与我的问题几乎无关,所以我第二次发布它

嗨,我想从RelativeLayout中捕获图像,为此我使用了以下代码

   captureRelativeLayout.setDrawingCacheEnabled(true);
   bitmap = captureRelativeLayout.getDrawingCache(true).copy(
                Config.ARGB_8888, false);

问题在于,当我启动活动并从该视图获取图像时,它会正常工作,但如果我第二次使用它,则图像不会被刷新,这意味着我每次获取的都是先前的位图。
现在,如果我关闭我的活动并重新启动它,那么我将获得更新后的图像,但再次使用时仍然无法刷新。
:( 更多信息请参见无法正确共享图像android

是的,我也尝试过那个方法 :( 但仍然出现问题。 - Siddhpura Amit
我可以给出的建议是:定期使用不同的名称保存位图。将文件名基于当前时间(如果精确到秒,则可能足够,否则也可以使用毫秒)。 - Phantômaxx
@ArtooDetoo 或者时间+日期 :) - john
是的,我的意思是:yyyyMMdd_HHmmss,确切地说 - 带上你的应用程序名称前缀 ;) - Phantômaxx
我已经尝试使用100000个随机数,但在每个新图像中,它都会存储其先前的图像,主要问题是视图没有刷新。 - Siddhpura Amit
我尝试使用captureRelativeLayout.getDrawingCache(false).copy(Config.ARGB_8888, false)进行工作;如果这是您需要的答案,请告诉我。 - Imtiyaz Khalani
6个回答

8
这里有两种将视图转换为位图的方式:

使用绘图缓存:

RelativeLayout view = (RelativeLayout)findViewById(R.id.relativelayout);
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = view.getDrawingCache();
view.setDrawingCacheEnabled(false);

当视图非常大时(例如在ScrollView中存在一个跨越整个可见屏幕的TextView),使用绘制缓存方法可能会出现问题。此时,使用下面的方法会更好。

使用画布(Canvas):

RelativeLayout view = (RelativeLayout)findViewById(R.id.relativelayout);
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
Drawable bgDrawable = view.getBackground();
if (bgDrawable != null) {
    bgDrawable.draw(canvas);
} else {
    canvas.drawColor(Color.WHITE);
}
view.draw(canvas);

7

在复制完绘图缓存之后,您应该将其销毁,这样下一次调用getDrawingCache()时,缓存将再次构建。

代码如下:

captureRelativeLayout.setDrawingCacheEnabled(true);
bitmap = captureRelativeLayout.getDrawingCache(true).copy(Config.ARGB_8888, false);
captureRelativeLayout.destroyDrawingCache();

如果你不想启用标志,也可以这样做:

captureRelativeLayout.buildDrawingCache(true);
bitmap = captureRelativeLayout.getDrawingCache(true).copy(Config.ARGB_8888, false);
captureRelativeLayout.destroyDrawingCache();

参考资料:https://groups.google.com/d/msg/android-developers/IkRXuMtOA5w/zlP6SKlfX-0J


2

在Android KTX中有一个Kotlin扩展函数:

val config: Bitmap.Config = Bitmap.Config.ARGB_8888
val bitmap = canvasView.drawToBitmap(config)

2
画布视图在哪里? - famfamfam

1

由于DrawingCache已过时,因此在Kotlin中:

fun View.createBitmap(): Bitmap {
    val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
    Canvas(bitmap).apply {
        background?.draw(this) ?: this.drawColor(Color.WHITE)
        draw(this)
    }
    return bitmap
}

1
最终我从这里找到了解决方案: view.getDrawingCache()只能使用一次 我只是忘了加上

     captureRelativeLayout.setDrawingCacheEnabled(false);

我已经通过以下代码完成了它,
    try {
        if (bitmap != null) {
            bitmap.recycle();
            bitmap = null;
        }
        Intent sharingIntent = new Intent(Intent.ACTION_SEND);
        captureRelativeLayout.setDrawingCacheEnabled(true);
        File sdcard = Environment.getExternalStorageDirectory();
        File f = new File(sdcard, "temp.jpg");
        FileOutputStream out = null;
        out = new FileOutputStream(f);
        captureRelativeLayout.setDrawingCacheEnabled(true);
        bitmap = captureRelativeLayout.getDrawingCache(true).copy(
                Config.ARGB_8888, false);
        bitmap.compress(Bitmap.CompressFormat.JPEG, 90, out);
        out.close();
        captureRelativeLayout.setDrawingCacheEnabled(false);
        sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f)); // imageUri
        sharingIntent.setType("image/jpg");

        sharingIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(f)); // imageUri
        startActivity(Intent.createChooser(sharingIntent, "Share Image"));
    } catch (Exception e) {
        e.printStackTrace();
    }

0

view.setDrawingCacheEnabled(true);

view.buildDrawingCache();

Bitmap bitmap = view.getDrawingCache();

"bitmap"是最终的位图。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接