Obtener bitmap del vector dibujable

En mi aplicación, tengo que configurar un icono grande para una notificación. LargeIcon debe ser un bitmap, y mis dibujables son imágenes vectoriales (la nueva función en Android, consulte este enlace ). El problema es que cuando bash decodificar un recurso que es una imagen vectorial, obtengo un nulo devuelto.

Aquí está la muestra de código:

if (BitmapFactory.decodeResource(arg0.getResources(), R.drawable.vector_menu_objectifs) == null) Log.d("ISNULL", "NULL"); else Log.d("ISNULL", "NOT NULL"); 

En esta muestra, cuando reemplazo R.drawable.vector_menu_objectifs con una imagen “normal”, png por ejemplo, el resultado no es nulo (obtengo el bitmap correcto) ¿Hay algo que me falta?

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; } 

ACTUALIZAR:

Proyecto gradle:

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

Módulo gradle:

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

Puedes usar el siguiente método:

 @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; } 

que a veces combino con:

 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"); } } 

En función de las respuestas anteriores, se puede simplificar así para que coincida tanto con VectorDrawable como con BitmapDrawable y sea compatible al menos con 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"); } } 

Luego tienes que agregar en tu archivo gradle:

 android { defaultConfig { vectorDrawables.useSupportLibrary = true } } 

En pre-Lollipop usará VectorDrawableCompat y en Lollipop usará VectorDrawable.

EDITAR

He editado la condición siguiendo el comentario de @ user3109468

Felicitaciones a @Alexey

Aquí está la versión de Kotlin usa extensiones al Context

 fun Context.getBitmapFromVectorDrawable(drawableId: Int): Bitmap? { var drawable = ContextCompat.getDrawable(this, drawableId) ?: return null if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { drawable = DrawableCompat.wrap(drawable).mutate() } val bitmap = Bitmap.createBitmap( drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) ?: return null val canvas = Canvas(bitmap) drawable.setBounds(0, 0, canvas.width, canvas.height) drawable.draw(canvas) return bitmap } 

Ejemplo de uso en la Activity :

 val bitmap = this.getBitmapFromVectorDrawable(R.drawable.ic_done_white_24dp) 

Si está dispuesto a usar Android KTX para Kotlin, puede usar el método de extensión Drawable#toBitmap() para lograr el mismo efecto que las otras respuestas:

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

o

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

Para agregar este y otros métodos de extensión útiles, deberá agregar lo siguiente a su build.gradle nivel de build.gradle

 repositories { google() } dependencies { implementation 'androidx.core:core-ktx:1.0.0-alpha1' } 

Enlace a la fuente del método de extensión aquí .

Tenga en cuenta que esto funcionará para cualquier subclase de Drawable y si el Drawable es un BitmapDrawable de Drawable de Drawable BitmapDrawable para utilizar el Bitmap subyacente.

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

imageTeste.setImageBitmap (addGradient (bitmap));