In meiner Anwendung muss ich ein großes Symbol für eine Benachrichtigung setzen . LargeIcon muss eine Bitmap sein, und meine Drawables sind Vektorbilder (die neue Funktion in Android, siehe diesen Link ) Das Problem Wenn ich versuche, eine Ressource, die ein Vektorbild ist, zu entschlüsseln, wird eine Null zurückgegeben.
Hier ist das Codebeispiel:
if (BitmapFactory.decodeResource(arg0.getResources(), R.drawable.vector_menu_objectifs) == null)
Log.d("ISNULL", "NULL");
else
Log.d("ISNULL", "NOT NULL");
Wenn ich in diesem Beispiel R.drawable.vector_menu_objectifs durch ein "normales" Bild, ein png für ein Beispiel, ersetze, ist das Ergebnis nicht null (ich bekomme die richtige Bitmap).
Auf API überprüft: 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:
Projektabschluss:
dependencies {
classpath 'com.Android.tools.build:gradle:2.2.0-alpha5'
}
Modulgrad:
Android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
vectorDrawables.useSupportLibrary = true
}
...
}
...
Sie können die folgende Methode verwenden:
@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;
}
was ich manchmal kombiniere mit:
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");
}
}
Basierend auf den vorherigen Antworten kann es auf diese Weise vereinfacht werden, um sowohl VectorDrawable als auch BitmapDrawable abzugleichen und mit mindestens API 15 kompatibel zu sein.
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");
}
}
Dann müssen Sie Ihre Gradle-Datei hinzufügen:
Android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Bei Pre-Lollipop wird VectorDrawableCompat und bei Lollipop VectorDrawable verwendet.
Ich habe die Bedingung nach dem Kommentar von @ user3109468 bearbeitet
Wenn Sie bereit sind, Android KTX für Kotlin zu verwenden, können Sie die Erweiterungsmethode Drawable#toBitmap()
verwenden, um denselben Effekt wie die anderen Antworten zu erzielen:
val bitmap = AppCompatResources.getDrawable(requireContext(), drawableId).toBitmap()
oder
val bitmap = AppCompatResources.getDrawable(context, drawableId).toBitmap()
Um diese und weitere nützliche Erweiterungsmethoden hinzuzufügen, müssen Sie Folgendes auf Modulebene hinzufügen build.gradle
repositories {
google()
}
dependencies {
implementation 'androidx.core:core-ktx:1.0.0-alpha1'
}
Link zur Quelle der Erweiterungsmethode hier .
Beachten Sie, dass dies für any Unterklasse von Drawable
funktioniert. Wenn Drawable
eine BitmapDrawable
ist, wird die Verknüpfung zur Verwendung der zugrunde liegenden Bitmap
hergestellt.
Ein dickes Lob an @Alexey
Hier ist die Kotlin
-Version mit Erweiterungen zu 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
}
Beispiel für die Verwendung in Activity
:
val bitmap = this.getBitmapFromVectorDrawable(R.drawable.ic_done_white_24dp)
Getestet auf API 16 - JellyBean mit Vector Drawables
public static Bitmap getBitmapFromVectorDrawable(Context context, int drawableId) {
Drawable drawable = AppCompatResources.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;
Dank an alle !
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));
Wenn Ihr vector
-Bild intrinsicWidth
und intrinsicHeight
klein ist und Sie versuchen, die Bitmap in einer großen Ansicht anzuzeigen, wird das Ergebnis verschwommen sein.
In diesem Fall können Sie eine neue Breite/Höhe für Ihre Bitmap angeben, um ein besseres Bild zu erhalten (oder Sie können die Vektorgröße in xml erhöhen, aber desireWidth
und desireHeight
können flexibler sein).
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
}
Ich hoffe es hilft
Wenn Sie Ihre Ausgabe auf eine gewünschte Ausgabegröße skalieren möchten, versuchen Sie Folgendes:
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)