Screenshot of a View is not has the same size as the view?

Viewed 86

So, I'm trying to blur out my ContraintLayout what approach I took is

  1. Take a screenshot of the root view.
  2. Add an ImageView in the root view with layout param MATCH_PARENT and MATCH_PARENT.
  3. Blur that screenshot
  4. Set the screenshot bitmap to this ImageView.

But it's not working as expected. Any help would be appreciated.

Here is some relevant code I'm using.

override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)

        val imageView = ImageView(this)
        val param = ConstraintLayout.LayoutParams(
            ConstraintLayout.LayoutParams.MATCH_PARENT,
            ConstraintLayout.LayoutParams.MATCH_PARENT
        )
        imageView.layoutParams = param
        val bit = convertViewToBitmap(root)
        val blurred = blur(bit,25F)
        imageView.setImageBitmap(blurred)
        root.addView(imageView)
    }

To get the screenshot of a View

private fun convertViewToBitmap(view: View): Bitmap {
        val spec = View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED)
        view.measure(spec, spec)
        view.layout(0, 0, view.measuredWidth, view.measuredHeight)
        val b = Bitmap.createBitmap(view.measuredWidth, view.measuredHeight,
            Bitmap.Config.ARGB_8888)
        val c = Canvas(b)
        //c.translate((-view.scrollX).toFloat(), (-view.scrollY).toFloat())
        view.draw(c)
        return b
    }

To blur that ScreenShot

 var times = 0

    fun blur(bitmap: Bitmap, radius: Float): Bitmap? {
        val renderScript = RenderScript.create(this)
        val blurredBitmap = bitmap.copy(Bitmap.Config.ARGB_8888, true)
        val input: Allocation = Allocation.createFromBitmap(
            renderScript,
            blurredBitmap,
            Allocation.MipmapControl.MIPMAP_FULL,
            Allocation.USAGE_SHARED
        )
        val output: Allocation = Allocation.createTyped(renderScript, input.type)
        // Load up an instance of the specific script that we want to use.
        ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript)).apply {
            setInput(input)
            setRadius(radius)
            forEach(output)
        }
        output.copyTo(blurredBitmap)
        if (times < 5) {
            times += 1
            blur(blurredBitmap, radius)
        }
        return blurredBitmap
    }

Here is the XML file

<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:app="http://schemas.android.com/apk/res-auto"
    xmlns:tools="http://schemas.android.com/tools"
    android:id="@+id/root"
    android:background="@android:color/white"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context=".MainActivity">

    <TextView
        android:id="@+id/text"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="Hello World!"
        android:textSize="30sp"
        app:layout_constraintBottom_toBottomOf="parent"
        app:layout_constraintLeft_toLeftOf="parent"
        app:layout_constraintRight_toRightOf="parent"
        app:layout_constraintTop_toTopOf="parent"
        app:layout_constraintVertical_bias="0.20" />

</androidx.constraintlayout.widget.ConstraintLayout>

Here is the result enter image description here

1 Answers

Instead of taking the screenshot of the view and blurring it. try this:

  1. Blur the TextView using BlueMaskFilter

     float radius = yourTextView.getTextSize() / 3; 
     BlurMaskFilter filter = new BlurMaskFilter(radius, BlurMaskFilter.Blur.NORMAL);
     yourTextView.getPaint().setMaskFilter(filter);
    
  2. Convert the blurred TextView to BitMap and set it to the ImageView bitmap

Related