android读写位图,android - 从矢量绘图获取位图

android - 从矢量绘图获取位图

在我的应用程序中,我必须为通知设置一个大图标。LargeIcon必须是一个Bitmap,我的drawables是矢量图像(Android中的新功能,请看这个链接)问题是当我尝试解码作为矢量图像的资源时,我得到一个null返回。

以下是代码示例:

if (BitmapFactory.decodeResource(arg0.getResources(), R.drawable.vector_menu_objectifs) == null)

Log.d("ISNULL", "NULL");

else

Log.d("ISNULL", "NOT NULL");

在此示例中,当我用" normal"替换R.drawable.vector_menu_objectifs时。 image,例如png,结果不为null(我得到正确的位图)有什么我想念的吗?

8个解决方案

167 votes

检查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

}

...

}

...

Alexey answered 2019-08-13T22:27:07Z

58 votes

您可以使用以下方法:

@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");

}

}

snodnipper answered 2019-08-13T22:27:37Z

21 votes

基于之前的答案,可以简化它,以匹配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

}

}

在pre-Lollipop上它将使用VectorDrawableCompat,在Lollipop上它将使用VectorDrawable。

编辑

我在@ user3109468的评论之后编辑了这个条件

Eselfar answered 2019-08-13T22:28:24Z

12 votes

如果您愿意使用Android KTX for Kotlin,您可以使用扩展方法Drawable来实现与其他答案相同的效果:

val bitmap = AppCompatResources.getDrawable(requireContext(), drawableId).toBitmap()

要么

val bitmap = AppCompatResources.getDrawable(context, drawableId).toBitmap()

要添加此扩展方法和其他有用的扩展方法,您需要将以下内容添加到模块级别Drawable

repositories {

google()

}

dependencies {

implementation 'androidx.core:core-ktx:1.0.0-alpha1'

}

在此处链接到扩展方法的来源。

请注意,这适用于Drawable的任何子类,如果Drawable是BitmapDrawable,则它将快捷方式使用基础Bitmap。

David Rawson answered 2019-08-13T22:29:13Z

5 votes

感谢@Alexey

这是Activity版本使用扩展到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)

Gunhan answered 2019-08-13T22:29:52Z

0 votes

如果您的desireWidth图像desireHeight和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

}

希望它有所帮助

Phan Van Linh answered 2019-08-13T22:30:27Z

0 votes

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));

Amine answered 2019-08-13T22:30:46Z

0 votes

如果您希望能够将输出扩展到所需的输出大小,请尝试以下代码段:

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)

Hans answered 2019-08-13T22:31:13Z

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值