私のアプリケーションでは、通知用の大きなアイコンを設定する必要があります。 LargeIconはビットマップである必要があり、私のドロウアブルはベクター画像です(Androidの新機能、 このリンク を参照)問題は、ベクター画像であるリソースをデコードしようとすると、nullが返されることです戻ってきた。
コードのサンプルは次のとおりです。
if (BitmapFactory.decodeResource(arg0.getResources(), R.drawable.vector_menu_objectifs) == null)
Log.d("ISNULL", "NULL");
else
Log.d("ISNULL", "NOT NULL");
このサンプルでは、R.drawable.vector_menu_objectifsを「通常の」画像(例:png)に置き換えると、結果はnullではありません(正しいビットマップを取得します)不足しているものはありますか?
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;
}
更新:
プロジェクトのグラドル:
dependencies {
classpath 'com.Android.tools.build:gradle:2.2.0-alpha5'
}
モジュールのグラドル:
Android {
compileSdkVersion 23
buildToolsVersion '23.0.3'
defaultConfig {
minSdkVersion 16
targetSdkVersion 23
vectorDrawables.useSupportLibrary = true
}
...
}
...
次の方法を使用できます。
@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;
}
私は時々それと組み合わせます:
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");
}
}
前の回答に基づいて、VectorDrawableとBitmapDrawableの両方に一致し、少なくとも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");
}
}
次に、gradleファイルを追加する必要があります。
Android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
Lollipopより前ではVectorDrawableCompatを使用し、LollipopではVectorDrawableを使用します。
@ user3109468のコメントに従って条件を編集しました
Kotlinで Android KTX を使用する場合は、拡張メソッドDrawable#toBitmap()
を使用して、他の回答と同じ効果を実現できます。
val bitmap = AppCompatResources.getDrawable(requireContext(), drawableId).toBitmap()
または
val bitmap = AppCompatResources.getDrawable(context, drawableId).toBitmap()
これやその他の便利な拡張メソッドを追加するには、モジュールレベルのbuild.gradle
に以下を追加する必要があります
repositories {
google()
}
dependencies {
implementation 'androidx.core:core-ktx:1.0.0-alpha1'
}
これは、Drawable
のanyサブクラスで機能し、Drawable
がBitmapDrawable
である場合は、基礎となるBitmap
を使用するショートカットになることに注意してください。
@Alexeyへの称賛
以下は、Kotlin
の拡張機能を使用した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
}
Activity
の使用例:
val bitmap = this.getBitmapFromVectorDrawable(R.drawable.ic_done_white_24dp)
API 16でテスト済み-Vector Drawablesを使用したJellyBean
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;
ありがとうございます !
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));
vector
イメージintrinsicWidth
およびintrinsicHeight
が小さく、ビットマップを大きなビューに表示しようとすると、結果がぼやけます。
その場合、ビットマップに新しい幅/高さを指定して、より良い画像を取得できます(または、xmlのベクターサイズを大きくできますが、desireWidth
およびdesireHeight
の方が柔軟性が高い場合があります)。
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
}
お役に立てば幸いです
出力を目的の出力サイズにスケーリングできるようにする場合は、次のスニペットを試してください。
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)