벡터 드로어 블에서 비트 맵 가져 오기
내 응용 프로그램에서 알림을 위해 큰 아이콘을 설정해야합니다. 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'
}
모듈 gradle :
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");
}
}
Then you have to add in your gradle file:
android {
defaultConfig {
vectorDrawables.useSupportLibrary = true
}
}
On pre-Lollipop it will use VectorDrawableCompat and on Lollipop it will use VectorDrawable.
EDIT
I've edited the condition following the comment of @user3109468
If you are willing to use Android KTX for Kotlin you can use the extension method Drawable#toBitmap()
to achieve the same effect as the other answers:
val bitmap = AppCompatResources.getDrawable(requireContext(), drawableId).toBitmap()
or
val bitmap = AppCompatResources.getDrawable(context, drawableId).toBitmap()
To add this and other useful extension methods you will need to add the following to your module-level build.gradle
repositories {
google()
}
dependencies {
implementation 'androidx.core:core-ktx:1.0.0-alpha1'
}
Note that this will work for any subclass of Drawable
and if the Drawable
is a BitmapDrawable
it will shortcut to use the underlying Bitmap
.
Kudos to @Alexey
Here is the Kotlin
version using extensions to 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
}
Example usage in Activity
:
val bitmap = this.getBitmapFromVectorDrawable(R.drawable.ic_done_white_24dp)
If your vector
image intrinsicWidth
and intrinsicHeight
is small and you try to display the bitmap to a big view, then you will see the result is blur.
In that case, you can provide a new width/height for your bitmap to get the better image (or you can increase the vector size in xml, but provide the desireWidth
and desireHeight
may be more flexible).
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
}
Hope it help
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));
If you want to be able to scale your output to a desired output size, try the following snippet:
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)
Tested on API 16 - JellyBean with 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;
Thanks to all !
참고URL : https://stackoverflow.com/questions/33696488/getting-bitmap-from-vector-drawable
'program story' 카테고리의 다른 글
중복 된 코드는 단위 테스트에서 더 견딜 수 있습니까? (0) | 2020.08.14 |
---|---|
JavaScript를 사용하여 브라우저 언어를 얻는 방법 (0) | 2020.08.14 |
피카소의 애니메이션 로딩 이미지 (0) | 2020.08.14 |
Linux에서 GDB를 시작하는 동안 명령 줄 인수를 어떻게 전달합니까? (0) | 2020.08.14 |
스위프트 : 가드 vs if let (0) | 2020.08.14 |