Converting a view to Bitmap without displaying it in Android?

前端 未结 9 1724
渐次进展
渐次进展 2020-11-22 07:36

I will try to explain what exactly I need to do.

I have 3 separate screens say A,B,C. There is another screen called say HomeScreen where all the 3 screens bitmap sh

相关标签:
9条回答
  • 2020-11-22 07:59
    view.setDrawingCacheEnabled(true);
    Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
    view.setDrawingCacheEnabled(false);
    
    0 讨论(0)
  • 2020-11-22 08:06

    here is my solution:

    public static Bitmap getBitmapFromView(View view) {
        Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(returnedBitmap);
        Drawable bgDrawable =view.getBackground();
        if (bgDrawable!=null) 
            bgDrawable.draw(canvas);
        else 
            canvas.drawColor(Color.WHITE);
        view.draw(canvas);
        return returnedBitmap;
    }
    

    Enjoy :)

    0 讨论(0)
  • 2020-11-22 08:08

    I know this may be a stale issue, but I was having problems getting any of these solutions to work for me. Specifically, I found that if any changes were made to the view after it was inflated that those changes would not get incorporated into the rendered bitmap.

    Here's the method which ended up working for my case. With one caveat, however. prior to calling getViewBitmap(View) I inflated my view and asked it to layout with known dimensions. This was needed since my view layout would make it zero height/width until content was placed inside.

    View view = LayoutInflater.from(context).inflate(layoutID, null);
    //Do some stuff to the view, like add an ImageView, etc.
    view.layout(0, 0, width, height);
    
    Bitmap getViewBitmap(View view)
    {
        //Get the dimensions of the view so we can re-layout the view at its current size
        //and create a bitmap of the same size 
        int width = view.getWidth();
        int height = view.getHeight();
    
        int measuredWidth = View.MeasureSpec.makeMeasureSpec(width, View.MeasureSpec.EXACTLY);
        int measuredHeight = View.MeasureSpec.makeMeasureSpec(height, View.MeasureSpec.EXACTLY);
    
        //Cause the view to re-layout
        view.measure(measuredWidth, measuredHeight);
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
    
        //Create a bitmap backed Canvas to draw the view into
        Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
    
        //Now that the view is laid out and we have a canvas, ask the view to draw itself into the canvas
        view.draw(c);
    
        return b;
    }
    

    The "magic sauce" for me was found here: https://groups.google.com/forum/#!topic/android-developers/BxIBAOeTA1Q

    Cheers,

    Levi

    0 讨论(0)
  • 2020-11-22 08:09

    there is a way to do this. you have to create a Bitmap and a Canvas and call view.draw(canvas);

    here is the code:

    public static Bitmap loadBitmapFromView(View v) {
        Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);                
        Canvas c = new Canvas(b);
        v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
        v.draw(c);
        return b;
    }
    

    if the view wasn't displayed before the size of it will be zero. Its possible to measure it like this:

    if (v.getMeasuredHeight() <= 0) {
        v.measure(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        Bitmap b = Bitmap.createBitmap(v.getMeasuredWidth(), v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas c = new Canvas(b);
        v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
        v.draw(c);
        return b;
    }
    

    EDIT: according to this post, Passing WRAP_CONTENT as value to makeMeasureSpec() doesn't to do any good (although for some view classes it does work), and the recommended method is:

    // Either this
    int specWidth = MeasureSpec.makeMeasureSpec(parentWidth, MeasureSpec.AT_MOST);
    // Or this
    int specWidth = MeasureSpec.makeMeasureSpec(0 /* any */, MeasureSpec.UNSPECIFIED);
    view.measure(specWidth, specWidth);
    int questionWidth = view.getMeasuredWidth();
    
    0 讨论(0)
  • 2020-11-22 08:12

    Try this,

    /**
     * Draw the view into a bitmap.
     */
    public static Bitmap getViewBitmap(View v) {
        v.clearFocus();
        v.setPressed(false);
    
        boolean willNotCache = v.willNotCacheDrawing();
        v.setWillNotCacheDrawing(false);
    
        // Reset the drawing cache background color to fully transparent
        // for the duration of this operation
        int color = v.getDrawingCacheBackgroundColor();
        v.setDrawingCacheBackgroundColor(0);
    
        if (color != 0) {
            v.destroyDrawingCache();
        }
        v.buildDrawingCache();
        Bitmap cacheBitmap = v.getDrawingCache();
        if (cacheBitmap == null) {
            Log.e(TAG, "failed getViewBitmap(" + v + ")", new RuntimeException());
            return null;
        }
    
        Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
    
        // Restore the view
        v.destroyDrawingCache();
        v.setWillNotCacheDrawing(willNotCache);
        v.setDrawingCacheBackgroundColor(color);
    
        return bitmap;
    }
    
    0 讨论(0)
  • 2020-11-22 08:12

    Hope this helps

    View view="some view instance";        
    view.setDrawingCacheEnabled(true);
    Bitmap bitmap=view.getDrawingCache();
    view.setDrawingCacheEnabled(false);
    

    Update
    getDrawingCache() method is deprecated in API level 28. So look for other alternative for API level > 28.

    0 讨论(0)
提交回复
热议问题