How to convert a Drawable to a Bitmap?

Rob*_*Rob 918 android bitmap wallpaper android-drawable

I would like to set a certain Drawable as the device's wallpaper, but all wallpaper functions accept Bitmaps only. I cannot use WallpaperManager because I'm pre 2.1.

Also, my drawables are downloaded from the web and do not reside in R.drawable.

Pra*_*een 1260

这段代码有帮助.

Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
                                           R.drawable.icon_resource);
Run Code Online (Sandbox Code Playgroud)

这是一个下载图像的版本.

String name = c.getString(str_url);
URL url_value = new URL(name);
ImageView profile = (ImageView)v.findViewById(R.id.vdo_icon);
if (profile != null) {
    Bitmap mIcon1 =
        BitmapFactory.decodeStream(url_value.openConnection().getInputStream());
    profile.setImageBitmap(mIcon1);
}
Run Code Online (Sandbox Code Playgroud)

  • 我想我找到了一些东西:如果"draw"是drawable我想转换成位图然后:Bitmap bitmap =((BitmapDrawable)draw).getBitmap(); 诀窍! (12认同)
  • 这不适用于 svgs。```BitmapFactory.decodeResource()``` 返回 null (3认同)
  • @Rob:如果您的 Drawable 只是 BitmapDrawable。(这意味着您的 Drawable 实际上只是 Bitmap 的包装) (2认同)
  • 注意:这会导致带有JPG的大量java.lang.OutOfMemoryError (2认同)

And*_*dré 728

public static Bitmap drawableToBitmap (Drawable drawable) {
    Bitmap bitmap = null;

    if (drawable instanceof BitmapDrawable) {
        BitmapDrawable bitmapDrawable = (BitmapDrawable) drawable;
        if(bitmapDrawable.getBitmap() != null) {
            return bitmapDrawable.getBitmap();
        }
    }

    if(drawable.getIntrinsicWidth() <= 0 || drawable.getIntrinsicHeight() <= 0) {
        bitmap = Bitmap.createBitmap(1, 1, Bitmap.Config.ARGB_8888); // Single color bitmap will be created of 1x1 pixel
    } else {
        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;
}
Run Code Online (Sandbox Code Playgroud)

  • 这看起来是唯一适用于任何类型的drawable的答案,并且还有一个已经是BitmapDrawable的drawable的快速解决方案.+1 (41认同)
  • 注意:如果drawable是纯色,`getIntrinsicWidth()`和`getIntrinsicHieght()`将返回-1. (16认同)
  • 所以...再次检查ColorDrawable,我们有一个胜利者.说真的,有人认为这是公认的答案. (5认同)
  • 与标记的答案相反,这回答了问题. (2认同)

Rob*_*Rob 211

这会将BitmapDrawable转换为Bitmap.

Drawable d = ImagesArrayList.get(0);  
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
Run Code Online (Sandbox Code Playgroud)

  • 不敢相信这64个赞成票吗?那个代码显然只有在`d`已经*是一个'BitmapDrawable`时才有效,在这种情况下,将它作为位图检索是微不足道的......在所有其他情况下,它会与`ClassCastException`崩溃. (354认同)
  • 这真的是最好的方式吗?当然drawable可能是另一种类型,这会抛出runtimeException吗?例如,它可能是一个9PatchDrawble ......? (9认同)
  • @Dori你可以在一个条件语句中包装代码,以检查它是否确实是一个`BitmapDrawable`在投之前:`if(d instanceof BitmapDrawable){Bitmap bitmap =((BitmapDrawable)d).getBitmap(); }` (4认同)
  • @Matthias更不用说..问题本身,同一作者,有100票:/ (3认同)
  • 这是一个专门针对一个微不足道的案例. (2认同)
  • 对于那些抱怨这是错误的人,你们有没有检查过关于页面的SO?它说接受的答案并不一定意味着答案是正确的,这意味着答案适用于OP. (2认同)
  • 惊喜是:当评论得到更多的投票而不是回答本身. (2认同)

kab*_*uko 140

A Drawable可以绘制到a Canvas,并且Canvas可以由以下内容支持Bitmap:

(已更新以处理BitmapDrawables 的快速转换并确保Bitmap创建的有效大小)

public static Bitmap drawableToBitmap (Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }

    int width = drawable.getIntrinsicWidth();
    width = width > 0 ? width : 1;
    int height = drawable.getIntrinsicHeight();
    height = height > 0 ? height : 1;

    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}
Run Code Online (Sandbox Code Playgroud)


Key*_*ani 42

方法1:您可以直接转换为这样的位图

Bitmap myLogo = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_drawable);
Run Code Online (Sandbox Code Playgroud)

方法2:您甚至可以将资源转换为drawable,从中可以获得这样的位图

Bitmap myLogo = ((BitmapDrawable)getResources().getDrawable(R.drawable.logo)).getBitmap();
Run Code Online (Sandbox Code Playgroud)

对于API> 22 getDrawable方法移动到ResourcesCompat类,所以你做这样的事情

Bitmap myLogo = ((BitmapDrawable) ResourcesCompat.getDrawable(context.getResources(), R.drawable.logo, null)).getBitmap();
Run Code Online (Sandbox Code Playgroud)


San*_*inh 37

1)可绘制到位图:

Bitmap mIcon = BitmapFactory.decodeResource(context.getResources(),R.drawable.icon);
// mImageView.setImageBitmap(mIcon);
Run Code Online (Sandbox Code Playgroud)

2) 位图到 Drawable :

Drawable mDrawable = new BitmapDrawable(getResources(), bitmap);
// mImageView.setDrawable(mDrawable);
Run Code Online (Sandbox Code Playgroud)

  • 该问题明确指出可绘制对象不驻留在 R.drawable 中。您的解决方案适用于 R.drawable。 (2认同)

MyD*_*Tom 35

android-ktx 有Drawable.toBitmap方法:https : //android.github.io/android-ktx/core-ktx/androidx.graphics.drawable/android.graphics.drawable.-drawable/to-bitmap.html

来自科特林

val bitmap = myDrawable.toBitmap()
Run Code Online (Sandbox Code Playgroud)

  • 这是 Kotlin 中 `VectorDrawable` 最简单的解决方案!还更详细地共享 [在此 SO 帖子中](/sf/answers/3621951721/)。 (2认同)

Erf*_*eri 31

非常简单

Bitmap tempBMP = BitmapFactory.decodeResource(getResources(),R.drawable.image);
Run Code Online (Sandbox Code Playgroud)

  • 这只是整整三年前对这个问题的[其他答案](http://stackoverflow.com/a/3035869/984830)的抄袭 (5认同)

Chr*_*ins 15

所以其他的答案中寻找(并使用)之后,他们似乎都处理ColorDrawablePaintDrawable严重.(特别是在棒棒糖上)似乎Shaders被调整,因此没有正确处理固体颜色块.

我现在使用以下代码:

public static Bitmap drawableToBitmap(Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable) drawable).getBitmap();
    }

    // We ask for the bounds if they have been set as they would be most
    // correct, then we check we are  > 0
    final int width = !drawable.getBounds().isEmpty() ?
            drawable.getBounds().width() : drawable.getIntrinsicWidth();

    final int height = !drawable.getBounds().isEmpty() ?
            drawable.getBounds().height() : drawable.getIntrinsicHeight();

    // Now we check we are > 0
    final Bitmap bitmap = Bitmap.createBitmap(width <= 0 ? 1 : width, height <= 0 ? 1 : height,
            Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}
Run Code Online (Sandbox Code Playgroud)

不像其他人,如果你拨打setBoundsDrawable要求把它变成一个位图前,将以此为位图以正确的尺寸!


Mau*_*uro 13

也许这会帮助别人......

从PictureDrawable到Bitmap,使用:

private Bitmap pictureDrawableToBitmap(PictureDrawable pictureDrawable){ 
    Bitmap bmp = Bitmap.createBitmap(pictureDrawable.getIntrinsicWidth(), pictureDrawable.getIntrinsicHeight(), Config.ARGB_8888); 
    Canvas canvas = new Canvas(bmp); 
    canvas.drawPicture(pictureDrawable.getPicture()); 
    return bmp; 
}
Run Code Online (Sandbox Code Playgroud)

......如此实施:

Bitmap bmp = pictureDrawableToBitmap((PictureDrawable) drawable);
Run Code Online (Sandbox Code Playgroud)

  • "也许这会帮助别人......" (4认同)

小智 13

最新的 androidx 核心库 (androidx.core:core-ktx:1.2.0) 现在有一个扩展功能:Drawable.toBitmap(...)将 Drawable 转换为 Bitmap。


Daw*_*ozd 11

这是更好的分辨率

public static Bitmap drawableToBitmap (Drawable drawable) {
    if (drawable instanceof BitmapDrawable) {
        return ((BitmapDrawable)drawable).getBitmap();
    }

    Bitmap bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap); 
    drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
    drawable.draw(canvas);

    return bitmap;
}

public static InputStream bitmapToInputStream(Bitmap bitmap) {
    int size = bitmap.getHeight() * bitmap.getRowBytes();
    ByteBuffer buffer = ByteBuffer.allocate(size);
    bitmap.copyPixelsToBuffer(buffer);
    return new ByteArrayInputStream(buffer.array());
}
Run Code Online (Sandbox Code Playgroud)

代码来自如何将可绘制位读取为InputStream


tas*_*iac 10

这是@ Chris.Jenkins在这里提供的答案的好Kotlin版本:https://stackoverflow.com/a/27543712/1016462

fun Drawable.toBitmap(): Bitmap {
  if (this is BitmapDrawable) {
    return bitmap
  }

  val width = if (bounds.isEmpty) intrinsicWidth else bounds.width()
  val height = if (bounds.isEmpty) intrinsicHeight else bounds.height()

  return Bitmap.createBitmap(width.nonZero(), height.nonZero(), Bitmap.Config.ARGB_8888).also {
    val canvas = Canvas(it)
    setBounds(0, 0, canvas.width, canvas.height)
    draw(canvas)
  }
}

private fun Int.nonZero() = if (this <= 0) 1 else this
Run Code Online (Sandbox Code Playgroud)


kc *_*ili 8

Android提供了一个非直接的解决方案:BitmapDrawable.为了得到位图,我们必须提供的资源ID R.drawable.flower_pic的一个BitmapDrawable,然后将其转换为Bitmap.

Bitmap bm = ((BitmapDrawable) getResources().getDrawable(R.drawable.flower_pic)).getBitmap();
Run Code Online (Sandbox Code Playgroud)


小智 5

使用此代码。它将帮助您实现目标。

 Bitmap bmp=BitmapFactory.decodeResource(getResources(), R.drawable.profileimage);
    if (bmp!=null) {
        Bitmap bitmap_round=getRoundedShape(bmp);
        if (bitmap_round!=null) {
            profileimage.setImageBitmap(bitmap_round);
        }
    }

  public Bitmap getRoundedShape(Bitmap scaleBitmapImage) {
    int targetWidth = 100;
    int targetHeight = 100;
    Bitmap targetBitmap = Bitmap.createBitmap(targetWidth, 
            targetHeight,Bitmap.Config.ARGB_8888);

    Canvas canvas = new Canvas(targetBitmap);
    Path path = new Path();
    path.addCircle(((float) targetWidth - 1) / 2,
            ((float) targetHeight - 1) / 2,
            (Math.min(((float) targetWidth), 
                    ((float) targetHeight)) / 2),
                    Path.Direction.CCW);

    canvas.clipPath(path);
    Bitmap sourceBitmap = scaleBitmapImage;
    canvas.drawBitmap(sourceBitmap, 
            new Rect(0, 0, sourceBitmap.getWidth(),
                    sourceBitmap.getHeight()), 
                    new Rect(0, 0, targetWidth, targetHeight), new Paint(Paint.FILTER_BITMAP_FLAG));
    return targetBitmap;
}
Run Code Online (Sandbox Code Playgroud)


Joh*_*Doe 5

BitmapFactory.decodeResource()自动缩放位图,因此您的位图可能变得模糊。为防止缩放,请执行以下操作:

BitmapFactory.Options options = new BitmapFactory.Options();
options.inScaled = false;
Bitmap source = BitmapFactory.decodeResource(context.getResources(),
                                             R.drawable.resource_name, options);
Run Code Online (Sandbox Code Playgroud)

或者

InputStream is = context.getResources().openRawResource(R.drawable.resource_name)
bitmap = BitmapFactory.decodeStream(is);
Run Code Online (Sandbox Code Playgroud)


Kis*_*nga 5

位图位图 = BitmapFactory.decodeResource(context.getResources(), R.drawable.icon);

这不会每次都起作用,例如,如果您的 drawable 是图层列表可绘制的,那么它会给出空响应,因此作为替代方案,您需要将您的 drawable 绘制到画布中然后另存为位图,请参考下面的代码。

public void drawableToBitMap(Context context, int drawable, int widthPixels, int heightPixels) {
    try {
        File file = new File(Environment.getExternalStoragePublicDirectory(Environment.DIRECTORY_DOWNLOADS) + "/", "drawable.png");
        FileOutputStream fOut = new FileOutputStream(file);
        Drawable drw = ResourcesCompat.getDrawable(context.getResources(), drawable, null);
        if (drw != null) {
            convertToBitmap(drw, widthPixels, heightPixels).compress(Bitmap.CompressFormat.PNG, 100, fOut);
        }
        fOut.flush();
        fOut.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
}

private Bitmap convertToBitmap(Drawable drawable, int widthPixels, int heightPixels) {
    Bitmap bitmap = Bitmap.createBitmap(widthPixels, heightPixels, Bitmap.Config.ARGB_8888);
    Canvas canvas = new Canvas(bitmap);
    drawable.setBounds(0, 0, widthPixels, heightPixels);
    drawable.draw(canvas);
    return bitmap;
}
Run Code Online (Sandbox Code Playgroud)

上面的代码将您可绘制的文件保存为下载目录中的 drawable.png