벡터 드로어 블에서 비트 맵 얻기 새로운 기능, 이 링크

내 응용 프로그램에서 알림에 큰 아이콘을 설정해야합니다. 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;
}