내 응용 프로그램에서 알림에 큰 아이콘을 설정해야합니다. 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;
}
최신 정보:
프로젝트 gradle :
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");
}
}
답변
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.2.0"
}
프로젝트에 종속성을 추가하는 최신 지침 은 여기 를 참조 하십시오 .
참고이를 위해 작동합니다 어떤 의 서브 클래스 Drawable
와 같은 경우 Drawable
입니다 BitmapDrawable
그것은 기본을 사용하는 바로 가기합니다 Bitmap
.
답변
이전 답변을 바탕으로 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
}
}
롤리팝 이전에서는 VectorDrawableCompat을 사용하고 롤리팝에서는 VectorDrawable을 사용합니다.
편집하다
@ user3109468의 의견에 따라 조건을 편집했습니다.
답변
@Alexey에게 Kudos
다음은 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에서 테스트-벡터 드로어 블이있는 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;
}
답변
다음 코드를 사용하여 이미지 를 올바른 종횡비 로 변환 하십시오 (예 : 알림 아이콘) :
public static Bitmap getBitmapFromVector(Context context, int drawableId) {
Drawable drawable = ContextCompat.getDrawable(context, drawableId);
int width = drawable.getIntrinsicWidth();
int height = drawable.getIntrinsicHeight();
Bitmap bitmap;
if (width < height) { //make a square
bitmap = Bitmap.createBitmap(height, height, Bitmap.Config.ARGB_8888);
} else {
bitmap = Bitmap.createBitmap(width, width, Bitmap.Config.ARGB_8888);
}
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0,
drawable.getIntrinsicWidth(), //use dimensions of Drawable
drawable.getIntrinsicHeight()
);
drawable.draw(canvas);
return bitmap;
}