0

I am using this class to blur the background of the root view in my activity:

object BlurBuilder {
private val BITMAP_SCALE = 0.4f
private val BLUR_RADIUS = 20f


fun blur(v: View): Bitmap {

    return calculateBlur(v.context, getScreenshot(v))
}


fun calculateBlur(ctx: Context, image: Bitmap): Bitmap {
    val width = Math.round(image.width * BITMAP_SCALE)
    val height = Math.round(image.height * BITMAP_SCALE)

    val inputBitmap = Bitmap.createScaledBitmap(image, width, height, false)
    val outputBitmap = Bitmap.createBitmap(inputBitmap)

    val rs = RenderScript.create(ctx)
    val theIntrinsic = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
    val tmpIn = Allocation.createFromBitmap(rs, inputBitmap)
    val tmpOut = Allocation.createFromBitmap(rs, outputBitmap)
    theIntrinsic.setRadius(BLUR_RADIUS)
    theIntrinsic.setInput(tmpIn)
    theIntrinsic.forEach(tmpOut)
    tmpOut.copyTo(outputBitmap)

    return outputBitmap
}


fun getScreenshot(v: View): Bitmap {
    val b = Bitmap.createBitmap(v.width, v.height, Bitmap.Config.ARGB_8888)
    val c = Canvas(b)
    v.draw(c)
    return b
    }
  }

And in my activity I have the following:

 fun applyBlur() {
    val view = this.findViewById(android.R.id.content).rootView

    if (view.width > 0) {
        val image = BlurBuilder.blur(view)

        window.setBackgroundDrawable(BitmapDrawable(this.resources, image))
    } else {
        view.viewTreeObserver.addOnGlobalLayoutListener({
            val image = BlurBuilder.blur(view)
            window.setBackgroundDrawable(BitmapDrawable(this.resources, image))
        })
    }
}

With this technique I blur the root view of my activity depending on the blur radius. How can I do the reverse ? I tried to put the BLUR_RADIUS to 0.1f but it still does not work.

Please provide some explanation on how can I achieve this. Thank you!

CyberUser
  • 348
  • 1
  • 4
  • 13

1 Answers1

1

Blur is a destructive operation and reversing it requires some complex math and computations, you'd better add a flag, and check it in the blur function, if the flag is false, for example -- just pass the original background through, like:

var contentBG: Drawable? = null
var needBlur = true
fun applyBlur() {
    val view = this.findViewById(android.R.id.content).rootView

    if (view.width > 0) {
        contentBG ?: let { contentBG = view.background }
        val drawable = if (needBlur)
            BitmapDrawable(this.resources, BlurBuilder.blur(view))
        else contentBG
        window.setBackgroundDrawable(drawable)
    } else {
        view.viewTreeObserver.addOnGlobalLayoutListener({
            val image = BlurBuilder.blur(view)
            window.setBackgroundDrawable(BitmapDrawable(this.resources, image))
        })
    }
}
Pavlus
  • 1,651
  • 1
  • 13
  • 24
  • I tried your idea, but unfortunately my root view background turns black. Why does this happen? – CyberUser Jun 24 '17 at 17:21
  • @GabrielKuka you used actually this solution or something like it? – Pavlus Jun 24 '17 at 17:23
  • Yes. I tried it. I set the isBlurNeeded to false when I have blurred the image so that it does not blur it again. But when I want to take it off it removes the blur and the background turns black. – CyberUser Jun 24 '17 at 17:27
  • Now it does returns to normal but if I want to blur it again it doesn't but instead turns black. Why is this happening in the first place? I don't understand – CyberUser Jun 24 '17 at 18:17
  • Anyway. I managed to fix it. The reason why it turned black was related to the child views of the activity. So I just did the same for child views. And now it works!! Thank you very much sir. – CyberUser Jun 24 '17 at 18:46