如何将Drawable位读取为InputStream

4

这里有一个 ImageView 对象。我想要将其位/原始数据作为 InputStream 读取。如何实现呢?


1
请查看 https://dev59.com/ZWw15IYBdhLWcg3wcrdC#36062748。 - Boris Treukhov
4个回答

14

首先将 ImageView 的背景图像作为 Drawable 对象获取:

iv.getBackground();

然后使用以下方式将Drawable图像转换为Bitmap

BitmapDrawable bitDw = ((BitmapDrawable) d);
Bitmap bitmap = bitDw.getBitmap();

现在使用ByteArrayOutputStreamBitmap转换为Stream并获取bytearray[],然后将bytearray转换为ByteArrayInputStream

您可以使用以下代码从ImageView获取InputStream

完整源代码

ImageView iv = (ImageView) findViewById(R.id.splashImageView);
Drawable d = iv.getBackground();
BitmapDrawable bitDw = ((BitmapDrawable) d);
Bitmap bitmap = bitDw.getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream);
byte[] imageInByte = stream.toByteArray();
System.out.println("........length......" + imageInByte);
ByteArrayInputStream bis = new ByteArrayInputStream(imageInByte);

谢谢 Deepak


以这种方式重新压缩它! - Perry

6
以下方法非常有用,因为它们适用于任何类型的Drawable(不仅限于BitmapDrawable)。如果您想使用David Caunt所建议的绘图缓存,请考虑使用bitmapToInputStream而不是bitmap.compress,因为它应该更快。
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());
}

它不会重新压缩图像,但为什么我必须分配位图像素,这会使内存占用量翻倍! - Perry

4
您可以使用绘图缓存来检索任何View类的位图表示。
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();

然后,您可以将位图写入OutputStream中,例如:
b.compress(CompressFormat.JPEG, 80, new FileOutputStream("/view.jpg"));

在您的情况下,我认为您可以使用ByteArrayOutputStream来获取一个byte[],从中可以创建一个InputStream。代码应该像这样:

ByteArrayOutputStream os = new ByteArrayOutputStream(b.getByteCount());
b.compress(CompressFormat.JPEG, 80, os);
byte[] bytes = os.toByteArray();

在问题中,Barmaley提到该问题是针对ImageView的。 - Sunil Kumar Sahoo
一个 ImageView 显示一张图片。为了捕获任何视图的渲染,包括 ImageView,在上面的代码将完成此工作。 - David Snabel-Caunt

1

我没有提到存储在资源中的图像。我说的是在屏幕上膨胀的ImageView对象(因此源未知)。 - Barmaley

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