将Drawable转换成byte[]

65

我在ImageView中有一张来自于网络的图片,它很小(一个网站图标),我想把它存储到我的SQLite数据库中。 我可以从mImageView.getDrawable()获取Drawable,但是我不知道接下来该怎么做。我并不完全理解Android中的Drawable类。

我知道可以通过以下方式从Bitmap获取字节数组:

Bitmap defaultIcon = BitmapFactory.decodeStream(in);

ByteArrayOutputStream stream = new ByteArrayOutputStream();
defaultIcon.compress(Bitmap.CompressFormat.JPEG, 100, stream);

byte[] bitmapdata = stream.toByteArray();

但是我该如何从Drawable中获取字节数组呢?

6个回答

149
Drawable d; // the drawable (Captain Obvious, to the rescue!!!)
Bitmap bitmap = ((BitmapDrawable)d).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitmapdata = stream.toByteArray();

谢谢你指出来!我没想到要进行类型转换。 - David Shellabarger
9
应该是:bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream); 否则流中将不包含任何数据... - Entreco
@Cristian 我将BitmapData以BLOB的形式保存在数据库中,但是当我从BLOB中恢复我的可绘制对象时,背景变成了黑色。你能帮我吗?我想要背景透明,就像保存到数据库之前一样。 - Sazzad Hissain Khan
1
@Hissain,因为JPG不支持透明度,所以你需要使用PNG。 - EpicPandaForce
注意:在大多数情况下,将JPEG压缩到90(而不是100)将是最佳选择! - Kirill Karmazin
为什么是90或者100?这两个选择有何意义? - Ryhan

22

感谢大家,这解决了我的问题。

Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.my_pic);
Bitmap bitmap = ((BitmapDrawable)drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitMapData = stream.toByteArray();

我把位图数据保存在数据库中作为二进制大对象(BLOB),但是当我从BLOB中重新获取可绘制对象时,背景变成了黑色。你能帮我吗?我希望在保存到数据库之前背景仍然透明。 - Sazzad Hissain Khan
我认为这是一个与该进程并行发生的不同问题。如果您能提供更多详细信息以便重现和检查,那就太好了。 - Randula
1
保存为JPEG格式时出现问题,但我改成PNG格式后就正常了... - Sazzad Hissain Khan

10
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.tester);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] bitMapData = stream.toByteArray();

这是一个更好的答案,因为它不需要将drawable强制转换为BitmapDrawable,而该drawable实际上可能不是BitmapDrawable的实例。 - matt snider
@mattsnider 谢谢 - Kalpesh

3

这是我的实用函数,可以复制粘贴使用

/**
 * @param ctx the context
 * @param res the resource id
 * @return the byte[] data of the fiven drawable identified with the resId
 */
public static byte[] getDrawableFromRes(Context ctx, @DrawableRes int res) {
    Bitmap bitmap = BitmapFactory.decodeResource(ctx.getResources(), res);
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
    return stream.toByteArray();
}

0
如果Drawable是BitmapDrawable,你可以尝试这个方法。
long getSizeInBytes(Drawable drawable) {
    if (drawable == null)
        return 0;

    Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
    return bitmap.getRowBytes() * bitmap.getHeight();
}

Bitmap.getRowBytes() 返回位图像素行之间的字节数。

更多信息请参考此项目:LazyList


1
此帖子因为只有代码而被自动标记为低质量。您能否加入一些文字来解释它是如何解决问题的? - gung - Reinstate Monica

-2
File myFile = new File(selectedImagePath);

byte [] mybytearray  = new byte [filelenghth];

BufferedInputStream bis1 = new BufferedInputStream(new FileInputStream(myFile));

bis1.read(mybytearray,0,mybytearray.length);

现在图像已经存储在字节数组中了...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接