How to read drawable bits as InputStream - android

There's say some ImageView object. I want to read bits/raw data of this object as InputStream. How to do that?

First get background image of the ImageView as an object of Drawable:
iv.getBackground();
Then convert Drawable image into Bitmap using
BitmapDrawable bitDw = ((BitmapDrawable) d);
Bitmap bitmap = bitDw.getBitmap();
Now use ByteArrayOutputStream to get the Bitmap into a Stream and get bytearray[]; then
convert the bytearray into a ByteArrayInputStream.
You can use the following code to get InputStream from ImageView.
Full Source code
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);
Thanks
Deepak

These methods below are useful because they work with any kind of Drawable (not only BitmapDrawable). If you want to use drawing cache as in David Caunt's suggestion, consider using bitmapToInputStream instead of bitmap.compress, because it should be faster.
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());
}

You can use the drawing cache to retrieve a Bitmap representation of any View class.
view.setDrawingCacheEnabled(true);
Bitmap b = view.getDrawingCache();
Then you can write the bitmap to an OutputStream, for example:
b.compress(CompressFormat.JPEG, 80, new FileOutputStream("/view.jpg"));
In your case I think you can use a ByteArrayOutputStream to get a byte[] from which you can create an InputStream. The code would be something like this:
ByteArrayOutputStream os = new ByteArrayOutputStream(b.getByteCount());
b.compress(CompressFormat.JPEG, 80, os);
byte[] bytes = os.toByteArray();

You might be looking for this:
openRawResource

Related

Convert ImageView Vector Drawable to Bitmap Android

I take a fingerprint from the user and add white background to it using glide. The issue is I need to get the byte array of that image and I can't get it because the Image being hold into the ImageView is a VectorDrawable. I am unable to convert this back to bitmap and thus to a byte array. I tried using it on a dummy png image like following.
Take any dummy PNG Image
firstIV = findViewById(R.id.firstIV);
secondIV = findViewById(R.id.secondIV);
Bitmap currentBmp = BitmapFactory.decodeResource(getResources(), R.drawable.test_image);
Glide.with(this).load(currentBmp).into(new SimpleTarget<Drawable>() {
#Override
public void onResourceReady(Drawable resource, Transition<? super Drawable> glideAnimation) {
final ShapeDrawable background = new ShapeDrawable();
background.getPaint().setColor(Color.WHITE);
final Drawable[] layers = {background, resource};
firstIV.setImageDrawable(new LayerDrawable(layers));
setToAnotherImageView(firstIV.getDrawable().getIntrinsicWidth(), firstIV.getDrawable().getIntrinsicHeight());
}
});
Applied Solution
private void setToAnotherImageView(int width, int height) {
Log.e(TAG, "onCreate: " + width + ":" + height);
Bitmap convertedBmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(convertedBmp);
firstIV.draw(canvas);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
convertedBmp.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] byteArray = stream.toByteArray();
Bitmap newBmp = BitmapFactory.decodeByteArray(byteArray,0,byteArray.length);
secondIV.setImageBitmap(newBmp);
}
Upon doing so my app crashes with an exception saying the vector drawable can not be converted to bitmap. The following is the error:
Originally what I want to achieve
Originally I want the bytearray of the the picture I have stored in my ImageView so I can convert that bytearray to WSQ bytearray and the send it to my server. I am trying to achieve such with an example defined above.
UPDATE:
Just find out that there is a new way to get Bitmap from ImageView:
imageView.drawToBitmap() //draw from the ImageView size
imageView.drawable.toBitmap() //draw from original Drawable size (I guess)
Convert ImageView to ByteArray:
private fun getImageBytes(): ByteArray {
val bitmap = Bitmap.createBitmap(my_profile_imageView.width, my_profile_imageView.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
my_profile_imageView.draw(canvas)
val outputStream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
return outputStream.toByteArray()
}
However, it's not a good idea to store the image ByetArray in local, you should store the uri or url instead.
My question is a duplicate of How to get a Bitmap from VectorDrawable
However I solved it like this
private void setToAnotherImageView() {
Drawable drawable = firstIV.getDrawable();
Bitmap newBmp = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(newBmp);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
secondIV.setImageBitmap(newBmp);
}

Unable to convert vector drawable to bitmap drawable in android

I am trying to convert a bitmap to byte array in which i have taken an vector drawable image to bitmap and then i have converted it to byte array but when i open the application it shows me an error class cast exception unable to convert vector drawable to bitmap drawable.
Resources res = getResources();
Drawable drawable = res.getDrawable(R.drawable.ic_motorcycle_black);
if (drawable != null) {
drawable.setColorFilter(0xffff0000, PorterDuff.Mode.MULTIPLY);
}
Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
final byte[] bike = stream.toByteArray();
Error:
Caused by: java.lang.ClassCastException: android.graphics.drawable.VectorDrawable cannot be cast to android.graphics.drawable.BitmapDrawable
at codingtown.coconut.otherexpense.activity.AddNewExpenseCategoryActivity.intialize(AddNewExpenseCategoryActivity.java:82)
at codingtown.coconut.otherexpense.activity.AddNewExpenseCategoryActivity.onCreate(AddNewExpenseCategoryActivity.java:67)
at android.app.Activity.performCreate(Activity.java:6092)
at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1112)
You can try this. It works fine with me.
private BitmapDescriptor bitmapDescriptorFromVector(Context context, #DrawableRes int vectorDrawableResourceId) {
Drawable background = ContextCompat.getDrawable(context, R.drawable.ic_map_pin_filled_blue_48dp);
background.setBounds(0, 0, background.getIntrinsicWidth(), background.getIntrinsicHeight());
Drawable vectorDrawable = ContextCompat.getDrawable(context, vectorDrawableResourceId);
vectorDrawable.setBounds(40, 20, vectorDrawable.getIntrinsicWidth() + 40, vectorDrawable.getIntrinsicHeight() + 20);
Bitmap bitmap = Bitmap.createBitmap(background.getIntrinsicWidth(), background.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
background.draw(canvas);
vectorDrawable.draw(canvas);
return BitmapDescriptorFactory.fromBitmap(bitmap);
}
You cannot cast VectorDrawable to BitmapDrawable. They don't have a parent-child relationship. They both are direct subclasses of Drawable class.
to get a bitmap from drawable, you will need to create a Bitmap from the drawable metadata.
Probably something like this in a separate method,
try {
Bitmap bitmap;
bitmap = Bitmap.createBitmap(drawable.getIntrinsicWidth(), drawable.getIntrinsicHeight(), BITMAP_CONFIG);
Canvas canvas = new Canvas(bitmap);
drawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
drawable.draw(canvas);
return bitmap;
} catch (OutOfMemoryError e) {
// Handle the error
return null;
}

Byte array to bitmap converting issue

I am trying to implement Converting bitmap to byteArray android. I need to convert my byte[] to bitmap without compression. But everytime im getting whole black image. How to do it?
What I am doing:
int bytes = bmp.getByteCount();
ByteBuffer buffer = ByteBuffer.allocate(bytes);
bmp.copyPixelsToBuffer(buffer);
byte[] resarray = buffer.array();
And here how I get it to bitmap:
BitmapFactory.Options options = new
BitmapFactory.Options();
options.inScaled = false;
Bitmap bmp = BitmapFactory.decodeByteArray(barray,0, barray.length,options);
ImageView imageView = (ImageView) findViewById(R.id.resdetayimage);
imageView.setImageBitmap(bmp);`
EDIT
Bitmap factory decode only compressed things. Thats why my code not work. So I need something like:
Bitmap.Config configBmp = Bitmap.Config.valueOf(bitmap.getConfig().name());
Bitmap bitmap_tmp = Bitmap.createBitmap(width, height, configBmp);
ByteBuffer buffer = ByteBuffer.wrap(byteArray);
bitmap_tmp.copyPixelsFromBuffer(buffer);
But the code still not working. How can I implement this ? I got byte[] from intent.
Convert bitmap to byteArray
ByteArrayOutputStream bStream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 90, bStream);
byte[] mByteArray = bStream.toByteArray();
Convert byteArray to Bitmap
Bitmap bitmap = BitmapFactory.decodeByteArray(mByteArray , 0, mByteArray.length);
Use copyPixelsFromBuffer() as it is the reverse of copyPixelsToBuffer().

Get bitmap of videoview

Is there a way to take a screenshot of a video playing in video view. I searched on the forum but could not get the required info. I tried with
Bitmap bitmap = Bitmap.createBitmap(this.view.getWidth(), this.view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
and
mCustomVideoView.setDrawingCacheEnabled(true);
Bitmap videoView = mCustomVideoView.getDrawingCache(false);
But none of these methods were helpful.
Just make it with that:
videoview.buildDrawingCache();
Bitmap bitmap = yourvideoview.getDrawingCache();
 java.io.ByteArrayOutputStream stream=new java.io.ByteArrayOutputStream(); 
bitmap.compress(Bitmap.CompressFormat.WEBP, 90, stream);
byte[] videoByteArray=stream.toByteArray(); String video_str = Base64.encodeToString(videoByteArray, 0);
The output is the String video_str and the Bitmap bitmap.

create Bitmap from byteArray in android

I want to create a bitmap from a bytearray .
I tried the following codes
Bitmap bmp;
bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
and
ByteArrayInputStream bytes = new ByteArrayInputStream(data);
BitmapDrawable bmd = new BitmapDrawable(bytes);
bmp = bmd.getBitmap();
But ,When i am tring to initialize the Canvas object with the bitmap like
Canvas canvas = new Canvas(bmp);
It leads to an error
java.lang.IllegalStateException: Immutable bitmap passed to Canvas constructor
Then how to get a mutable bitmap from an byteArray.
Thanks in advance.
You need a mutable Bitmap in order to create the Canvas.
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length);
Bitmap mutableBitmap = bmp.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap); // now it should work ok
Edit: As Noah Seidman said, you can do it without creating a copy.
BitmapFactory.Options options = new BitmapFactory.Options();
options.inMutable = true;
Bitmap bmp = BitmapFactory.decodeByteArray(data, 0, data.length, options);
Canvas canvas = new Canvas(bmp); // now it should work ok

Categories

Resources