Getting Bitmap from vector drawable

Checked on API: 17, 21, 23

public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
    Drawable drawable = ContextCompat.getDrawable(context, drawableId);
    if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) {
        drawable = (DrawableCompat.wrap(drawable)).mutate();
    }

    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(),
            drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

UPDATE:

Project gradle:

dependencies {
        classpath 'com.android.tools.build:gradle:2.2.0-alpha5'
    }

Module gradle:

android {
    compileSdkVersion 23
    buildToolsVersion '23.0.3'
    defaultConfig {
        minSdkVersion 16
        targetSdkVersion 23
        vectorDrawables.useSupportLibrary = true
    }
    ...
}
...

You can use the following method:

@TargetApi(Build.VERSION_CODES.LOLLIPOP)
private static Bitmap getBitmap(VectorDrawable vectorDrawable) {
    Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
            vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    vectorDrawable.draw(canvas);
    return bitmap;
}

which I sometimes combine with:

private static Bitmap getBitmap(Context context, int drawableId) {
    Drawable drawable = ContextCompat.getDrawable(context, drawableId);
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    } else if (drawable instanceof VectorDrawable) {
        return getBitmap((VectorDrawable) drawable);
    } else {
        throw new IllegalArgumentException("unsupported drawable type");
    }
}

If you are willing to use Android KTX for Kotlin you can use the extension method Drawable#toBitmap() to achieve the same effect as the other answers:

val bitmap = AppCompatResources.getDrawable(requireContext(), drawableId).toBitmap() 

or

val bitmap = AppCompatResources.getDrawable(context, drawableId).toBitmap() 

To add this and other useful extension methods you will need to add the following to your module-level build.gradle

repositories {
    google()
}

dependencies {
    implementation "androidx.core:core-ktx:1.2.0"
}

See here for latest instructions for adding the dependency to your project.

Note that this will work for any subclass of Drawable and if the Drawable is a BitmapDrawable it will shortcut to use the underlying Bitmap.


Based on the previous answers it can be simplified like that to match both VectorDrawable and BitmapDrawable and to be compatible with at least API 15.

public static Bitmap getBitmapFromDrawable(Context context, @DrawableRes int drawableId) {
    Drawable drawable = AppCompatResources.getDrawable(context, drawableId);

    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    } else if (drawable instanceof VectorDrawableCompat || drawable instanceof VectorDrawable) {
        Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(bitmap);
        drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
        drawable.draw(canvas);

        return bitmap;
    } else {
        throw new IllegalArgumentException("unsupported drawable type");
    }
}

Then you have to add in your gradle file:

android {
    defaultConfig {
        vectorDrawables.useSupportLibrary = true
    }
}

On pre-Lollipop it will use VectorDrawableCompat and on Lollipop it will use VectorDrawable.

EDIT

I've edited the condition following the comment of @user3109468

EDIT 2 (10/2020)

At least from API 21 you can now use this instead of the above code (I haven't tried on previous API versions):

AppCompatResources.getDrawable(context, R.drawable.your_drawable)