1

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.

  • I wasn't able to reproduce the problem: your first approach as posted here leads to a NullPointerException because you try to access the drawable of imageView1 before it has been set (`onResourceReady()` can only run once the current method has finished). So I moved the problem lines to the end of `onResourceReady()`. Now I am getting a ClassCastException but it's not about VectorDrawables. Anyhow, I was able to fix the issue with the method you posted here, and now I have two ImageViews with more or less the same drawable (difference is likely due to different scaleTypes) (cont) – Bö macht Blau Feb 24 '21 at 14:49
  • (cont) So the conversion to Bitmap did work, mission accomplished. Unfortunately I don't know what you should change since I can't see what exactly you are currently doing. Please add more code if you still need help – Bö macht Blau Feb 24 '21 at 14:51
  • There are two ImageViews i set the first ImageView with PNG file and add a white background to it doing all this using Glide. After the Image is set to first ImageView I want the Bitmap of that ImageView and set it to my second ImageView. I am unable to get the Bitmap from first ImageView because of the error of conversion from VectorDrawable to Bitmap. – muhammad Yousuf Feb 25 '21 at 09:56
  • Which line gives error? – Sam Chen Mar 02 '21 at 14:43
  • BTW, I updated my answer. – Sam Chen Mar 02 '21 at 14:46

2 Answers2

0

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.

Sam Chen
  • 2,491
  • 1
  • 17
  • 31
  • Originally I want the bytearray of the picture stored in my first ImageView but I don't know weather i get the proper bytearray or not so to check whether i get the correct bytearray or not i try to get the Bitmap of first ImageView and set it to second ImageView but unable to do so. If i am able to do so I will compare the bytearray of both ImageViews. – muhammad Yousuf Feb 25 '21 at 09:53
  • Am I making sense to you? – muhammad Yousuf Feb 25 '21 at 09:55
  • @muhammad Yousuf So does my answer help? – Sam Chen Feb 25 '21 at 16:34
  • I am unable to recreate the image, I tried to get the byte array like you suggested but when I try to convert the bytearray again to a Bitmap and set it to image it doesn't show any image. I'll update the question according to your solution – muhammad Yousuf Mar 02 '21 at 09:57
  • There is no such method in java there is way to get the bitmap which is: Bitmap bitmap = ((BitmapDrawable)firstIV.getDrawable()).getBitmap();, It gives an error for casting of VectorDrawable to Bitmap. – muhammad Yousuf Mar 03 '21 at 12:41
  • 1
    @muhammad Yousuf Yes, I got that from here: https://stackoverflow.com/a/57865751/3466808. This post also answeres your question I think. – Sam Chen Mar 03 '21 at 15:08
  • thanks for the link it solves my problem :) – muhammad Yousuf Mar 03 '21 at 15:54
0

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