DEV Community

Pranav Pandey
Pranav Pandey

Posted on • Edited on

Android — Create Bitmap from a View

Header

Hello everyone! This is my first programming tutorial here in which I will discuss about creating the bitmap from a view at runtime.

Background

I have an app for Android in which users can customise all the theme colors according to their requirement. They can also copy or share their theme in the form of a JSON which can be imported to achieve the exactly same look later or can be shared between the other devices.

Recently, I decided to generate an image from the theme preview which users can share along with the JSON to give some idea about the theme before importing it. The in-app preview already shows the theme before applying it but I wanted to provide the similar kind of functionality for posts shared on social media and in other communities.

Implementation

View.getDrawingCache()

Initially, I tried to use the view drawing cache. Although, it is working fine but most of the drawing cache related methods are deprecated in Android 9 (API 28). Please check the deprecated code below:

    /**
     * Creates a bitmap from the supplied view.
     *
     * @param view The view to get the bitmap.
     * @param width The width for the bitmap.
     * @param height The height for the bitmap.
     *
     * @return The bitmap from the supplied drawable.
     */
    public @NonNull static Bitmap createBitmapFromView(@NonNull View view, int width, int height) {
        if (width > 0 && height > 0) {
            view.measure(View.MeasureSpec.makeMeasureSpec(DynamicUnitUtils
                            .convertDpToPixels(width), View.MeasureSpec.EXACTLY),
                    View.MeasureSpec.makeMeasureSpec(DynamicUnitUtils
                            .convertDpToPixels(height), View.MeasureSpec.EXACTLY));
        }

        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache(true);
        Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
        view.setDrawingCacheEnabled(false);

        return bitmap;
    }
Enter fullscreen mode Exit fullscreen mode

Canvas

As drawing cache API is deprecated, I found that we can achieve the similar result by using the Canvas API. Please check the new code below:

    /**
     * Creates a bitmap from the supplied view.
     *
     * @param view The view to get the bitmap.
     * @param width The width for the bitmap.
     * @param height The height for the bitmap.
     *
     * @return The bitmap from the supplied drawable.
     */
    public @NonNull static Bitmap createBitmapFromView(@NonNull View view, int width, int height) {
        if (width > 0 && height > 0) {
            view.measure(View.MeasureSpec.makeMeasureSpec(DynamicUnitUtils
                            .convertDpToPixels(width), View.MeasureSpec.EXACTLY),
                    View.MeasureSpec.makeMeasureSpec(DynamicUnitUtils
                            .convertDpToPixels(height), View.MeasureSpec.EXACTLY));
        }
        view.layout(0, 0, view.getMeasuredWidth(), view.getMeasuredHeight());

        Bitmap bitmap = Bitmap.createBitmap(view.getMeasuredWidth(),
                view.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        Drawable background = view.getBackground();

        if (background != null) {
            background.draw(canvas);
        }
        view.draw(canvas);

        return bitmap;
    }
Enter fullscreen mode Exit fullscreen mode

Pass 0 for height or width to use the current view dimensions.
You can check the code for DynamicUnitUtils.convertDpToPixels(float) method here.

Outputs from both the methods are similar but it is recommended to use the canvas API as the view drawing cache methods may not work in the future releases of Android.

Output

PixelCopy

There is another API for Android 7.0 (API 24+) or above devices which you can use to take screenshots of the UI. It seems complicated to me and I have not tried it yet. You can check the official documentation here.

Dynamic Utils

I have created a library for similar kind of utility methods related to color, device, drawable, package, tasks, SDK, etc. which you can use to perform various runtime (dynamic) operations. Please visit the GitHub page for more info.

GitHub logo pranavpandey / dynamic-utils

Utility functions to perform dynamic operations on Android.

Dynamic Utils

License Release

A collection of static methods and packages to perform dynamic operations on Android 2.3 (API 9) and above.

Since v0.4.0, it uses 26.x.x support libraries so, minimum SDK will be Android 4.0 (API 14)
Since v2.0.0, it uses AndroidX so, first migrate your project to AndroidX
Since v3.3.0, added Concurrent package to replace the deprecated AsyncTask API.
Since v4.1.0, it is dependent on Java 8 due to the dependency on AndroidX Core.
Since v4.3.0, it supports some helper methods to capture results via Barquode app.
Since v4.5.1, it is targeting Java 17 to provide maximum compatibility.
Since v4.6.0, the minimum SDK is Android 4.4 (API 19) to comply with the latest policies.


Contents


Installation

It can be installed by adding the following dependency to your build.gradle

This is my initial attempt on blogging so, I will keep improving the future posts. Please comment to give suggestions and what you want to see in the future posts. Thanks for your time!

Top comments (3)

Collapse
 
abbasalim profile image
Abbasali

very very thanks

Collapse
 
misaki1301 profile image
Paul Frank

Will it possible to convert an external xml ex."custom_marker.xml", inflate the view (on the Activity) and make a bitmap of it with your library? It'll be great!! Anyway thanks for the post :)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.