【问题标题】:Convert ImageView Vector Drawable to Bitmap Android将 ImageView Vector Drawable 转换为 Android 位图
【发布时间】:2021-02-24 12:41:58
【问题描述】:

我从用户那里获取指纹,并使用 glide 为其添加白色背景。问题是我需要获取该图像的字节数组,但我无法获取它,因为保存在 ImageView 中的图像是 VectorDrawable。我无法将其转换回位图,从而转换为字节数组。我尝试在虚拟 png 图像上使用它,如下所示。

获取任何虚拟 PNG 图像

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

    }
});

应用解决方案

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

这样做后,我的应用程序崩溃,并出现一个异常,指出矢量可绘制对象无法转换为位图。以下是错误:

本来我想要达到的

最初我想要存储在 ImageView 中的图片的字节数组,以便我可以将该字节数组转换为 WSQ 字节数组并将其发送到我的服务器。我正在尝试通过上面定义的示例来实现这一目标。

【问题讨论】:

  • 我无法重现该问题:您在此处发布的第一种方法会导致 NullPointerException,因为您尝试在设置之前访问 imageView1 的可绘制对象(onResourceReady() 只能运行一次当前方法已完成)。所以我将问题行移到onResourceReady() 的末尾。现在我得到了一个 ClassCastException,但它与 VectorDrawables 无关。无论如何,我能够使用您在此处发布的方法解决问题,现在我有两个 ImageView,它们或多或少具有相同的可绘制对象(差异可能是由于不同的 scaleTypes)(续)
  • (cont) 所以到位图的转换确实奏效了,任务完成了。不幸的是,我不知道你应该改变什么,因为我看不到你目前在做什么。如果您仍需要帮助,请添加更多代码
  • 有两个 ImageViews 我用 PNG 文件设置第一个 ImageView 并使用 Glide 为其添加白色背景。将图像设置为第一个 ImageView 后,我想要该 ImageView 的位图并将其设置为我的第二个 ImageView。由于从 VectorDrawable 到 Bitmap 的转换错误,我无法从第一个 ImageView 获取 Bitmap。
  • 哪一行出现错误?
  • 顺便说一句,我更新了我的答案。

标签: android android-glide android-vectordrawable


【解决方案1】:

更新:

只是发现有一种从ImageView 获取Bitmap 的新方法:

imageView.drawToBitmap()        //draw from the ImageView size
imageView.drawable.toBitmap()   //draw from original Drawable size (I guess)

ImageView 转换为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()
}

但是,将图像ByetArray 存储在本地不是一个好主意,您应该存储uriurl

【讨论】:

  • 最初我想将图片的字节数组存储在我的第一个 ImageView 中,但我不知道天气我是否得到了正确的字节数组,所以要检查我是否得到了正确的字节数组我试图得到第一个 ImageView 的位图并将其设置为第二个 ImageView 但无法这样做。如果我能够这样做,我将比较两个 ImageViews 的字节数组。
  • 我对你有意义吗?
  • @muhammad Yousuf 那么我的回答有帮助吗?
  • 我无法重新创建图像,我尝试按照您的建议获取字节数组,但是当我尝试再次将字节数组转换为位图并将其设置为图像时,它不显示任何图像.我会根据你的解决方案更新问题
  • @muhammad Yousuf 是的,我是从这里得到的:*.com/a/57865751/3466808。我认为这篇文章也回答了你的问题。
【解决方案2】:

我的问题与How to get a Bitmap from VectorDrawable重复

不过我是这样解决的

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

【讨论】: