如何将Drawable转换为位图?

时间:2010-06-14 07:46:36

标签: android bitmap wallpaper android-drawable

我想将某个Drawable设置为设备的壁纸,但所有壁纸功能仅接受Bitmap。我不能使用WallpaperManager因为我是2.1之前。

此外,我的drawables是从网上下载的,不在R.drawable

20 个答案:

答案 0 :(得分:1211)

这段代码有帮助。

Bitmap icon = BitmapFactory.decodeResource(context.getResources(),
                                           R.drawable.icon_resource);

此处是下载图片的版本。

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

答案 1 :(得分:691)

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

答案 2 :(得分:204)

这会将BitmapDrawable转换为位图。

Drawable d = ImagesArrayList.get(0);  
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();

答案 3 :(得分:134)

可以在Drawable上绘制CanvasCanvas可以支持Bitmap

(已更新以处理BitmapDrawable的快速转换并确保创建的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;
}

答案 4 :(得分:32)

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

Bitmap myLogo = BitmapFactory.decodeResource(context.getResources(), R.drawable.my_drawable);

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

Bitmap myLogo = ((BitmapDrawable)getResources().getDrawable(R.drawable.logo)).getBitmap();

API&gt; 22 getDrawable方法已移至ResourcesCompat类,因此您可以执行此类操作

Bitmap myLogo = ((BitmapDrawable) ResourcesCompat.getDrawable(context.getResources(), R.drawable.logo, null)).getBitmap();

答案 5 :(得分:31)

非常简单

Bitmap tempBMP = BitmapFactory.decodeResource(getResources(),R.drawable.image);

答案 6 :(得分:14)

因此,在查看(和使用)其他答案后,似乎他们都严重处理ColorDrawablePaintDrawable。 (特别是在棒棒糖上)似乎Shader被调整了,因此没有正确处理明确的颜色块。

我现在使用以下代码:

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

与其他人不同,如果您在要求将其转换为位图之前在setBounds上调用Drawable,则会以正确的尺寸绘制位图!

答案 7 :(得分: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; 
}

......如此实施:

Bitmap bmp = pictureDrawableToBitmap((PictureDrawable) drawable);

答案 8 :(得分:12)

最新的androidx核心库(androidx.core:core-ktx:1.2.0)现在具有extension function: Drawable.toBitmap(...),可将Drawable转换为位图。

答案 9 :(得分:10)

这是更好的解决方案

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

来自How to read drawable bits as InputStream的代码

答案 10 :(得分:8)

Android提供了一种非直接的解决方案:BitmapDrawable。要获取位图,我们必须向a R.drawable.flower_pic提供资源ID BitmapDrawable,然后将其转换为Bitmap

Bitmap bm = ((BitmapDrawable) getResources().getDrawable(R.drawable.flower_pic)).getBitmap();

答案 11 :(得分:8)

以下是@ 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

答案 12 :(得分: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;
}

答案 13 :(得分:5)

1)可绘制到位图:

Bitmap mIcon = BitmapFactory.decodeResource(context.getResources(),R.drawable.icon);
// mImageView.setImageBitmap(mIcon);

2)位图到Drawable:

Drawable mDrawable = new BitmapDrawable(getResources(), bitmap);
// mImageView.setDrawable(mDrawable);

答案 14 :(得分:4)

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

例如,如果您的drawable是图层列表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;
}

以上代码可将您保存为drawable.png的下载目录

答案 15 :(得分:1)

 // get image path from gallery
protected void onActivityResult(int requestCode, int resultcode, Intent intent) {
    super.onActivityResult(requestCode, resultcode, intent);

    if (requestCode == 1) {
        if (intent != null && resultcode == RESULT_OK) {             
            Uri selectedImage = intent.getData();

            String[] filePathColumn = {MediaStore.Images.Media.DATA};
            Cursor cursor = getContentResolver().query(selectedImage, filePathColumn, null, null, null);
            cursor.moveToFirst();
            int columnIndex = cursor.getColumnIndex(filePathColumn[0]);
            filePath = cursor.getString(columnIndex);

            //display image using BitmapFactory

            cursor.close(); bmp = BitmapFactory.decodeFile(filepath); 
            iv.setBackgroundResource(0);
            iv.setImageBitmap(bmp);
        }
    }
}

答案 16 :(得分:1)

ImageWorker库可以将位图转换为drawable或base64,反之亦然。

Sub Test()
Dim arr, rng As Range, c As Range, n As Long

Set rng = Range("P2:P" & Cells(Rows.Count, "P").End(xlUp).Row).SpecialCells(xlCellTypeVisible)
ReDim a(1 To rng.Cells.Count)

For Each c In rng
    n = n + 1: a(n) = c.Value
Next c

arr = Join(a, ",")
End Sub

实施

在项目级别Gradle中

val bitmap: Bitmap? = ImageWorker.convert().drawableToBitmap(sourceDrawable)

在应用程序级别绑定中

allprojects {
        repositories {
            ...
            maven { url 'https://jitpack.io' }
        }
    }

您还可以从外部存储和检索位图/可绘制对象/ base64图像。

在这里检查。 https://github.com/1AboveAll/ImageWorker/edit/master/README.md

答案 17 :(得分:0)

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

来自Kotlin

val bitmap = myDrawable.toBitmap()

答案 18 :(得分:0)

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

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

InputStream is = context.getResources().openRawResource(R.drawable.resource_name)
bitmap = BitmapFactory.decodeStream(is);

答案 19 :(得分:0)

如果您正在使用kotlin,请使用以下代码。会起作用的

//用于使用图像路径

const [textareaValue, setTextareaValues] = React.useState([])

const handleSelectedItem = item => {
  setTextareaValues([...textareaValue, item]))
}