ventajas vectoriales vectorial usos una tipos que mapa imagenes imagen entre ejemplos diferencia desventajas corel android bitmap android-drawable vectordrawable android-vectordrawable

android - vectoriales - que es una imagen vectorial



Obteniendo mapa de bits del vector dibujable (8)

Comprobado en 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 } ... } ...

En mi aplicación, tengo que establecer un ícono grande para una notificación. LargeIcon debe ser un mapa de bits, y mis dibujos son imágenes vectoriales (la nueva característica en Android, vea este enlace ) El problema es que cuando intento decodificar un recurso que es una imagen vectorial, me devuelve un valor nulo.

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 este ejemplo, cuando reemplazo R.drawable.vector_menu_objectifs con una imagen "normal", un png por ejemplo, el resultado no es nulo (obtengo el mapa de bits correcto) ¿Hay algo que me falta?


En base a las respuestas anteriores, se puede simplificar así para que coincida con VectorDrawable y BitmapDrawable y para ser compatible con al menos 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 debe agregar su 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 para 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)


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


Si desea poder escalar su salida al tamaño de salida deseado, pruebe el siguiente fragmento:

fun getBitmapFromVectorDrawable(context: Context, drawableId: Int, outputSize: OutputSize? = null): Bitmap? { var drawable = ContextCompat.getDrawable(context, drawableId) ?: return null if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP) { drawable = DrawableCompat.wrap(drawable).mutate() } var targetBitmap: Bitmap if (outputSize != null) { targetBitmap = Bitmap.createBitmap(outputSize.width, outputSize.height, Bitmap.Config.ARGB_8888) } else { targetBitmap = Bitmap.createBitmap(drawable.intrinsicWidth, drawable.intrinsicHeight, Bitmap.Config.ARGB_8888) } val canvas = Canvas(targetBitmap) val scaleX = targetBitmap.width.toFloat()/drawable.intrinsicWidth.toFloat() val scaleY = targetBitmap.height.toFloat()/drawable.intrinsicHeight.toFloat() canvas.scale(scaleX, scaleY) drawable.draw(canvas) return targetBitmap } class OutputSize(val width: Int, val height: Int)


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

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


Si su imagen vector intrinsicWidth e intrinsicHeight es pequeña e intenta mostrar el mapa de bits en una vista grande, verá que el resultado es borroso.

En ese caso, puede proporcionar un nuevo ancho / alto para su mapa de bits para obtener la mejor imagen (o puede aumentar el tamaño del vector en xml, pero proporcionar el desireWidth y la desireWidth desireHeight pueden ser más flexibles).

private fun getBitmap(drawableId: Int, desireWidth: Int? = null, desireHeight: Int? = null): Bitmap? { val drawable = AppCompatResources.getDrawable(context, drawableId) ?: return null val bitmap = Bitmap.createBitmap( desireWidth ?: drawable.intrinsicWidth, desireHeight ?: drawable.intrinsicHeight, Bitmap.Config.ARGB_8888 ) val canvas = Canvas(bitmap) drawable.setBounds(0, 0, canvas.width, canvas.height) drawable.draw(canvas) return bitmap }

Espero que ayude


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