Skip to content
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
231 changes: 231 additions & 0 deletions app/src/main/java/me/bzcoder/webview/utils/BlurUtils.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
package me.bzcoder.easyglide.util

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The package name me.bzcoder.easyglide.util seems more related to image loading than general utilities. Consider moving this class to a more appropriate package like me.bzcoder.webview.utils to better reflect its purpose.

Suggested change
package me.bzcoder.easyglide.util
package me.bzcoder.webview.utils


import android.content.Context
import android.graphics.Bitmap
import android.os.Build
import android.renderscript.Allocation
import android.renderscript.Element
import android.renderscript.RenderScript
import android.renderscript.ScriptIntrinsicBlur
import androidx.annotation.RequiresApi
import android.view.View2

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

high

This import android.view.View2 seems incorrect. There is no View2 class in the Android SDK. It's likely a typo or an artifact of a copy/paste. Please remove it.


/**
* @author sunfusheng on 2018/6/25.
*/
object BlurUtils {
fun rsBlur(context: Context?, toTransform: Bitmap, radius: Int): Bitmap {
val renderScript = RenderScript.create(context)
val input = Allocation.createFromBitmap(renderScript, toTransform)
val output = Allocation.createTyped(renderScript, input.type)
val scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
scriptIntrinsicBlur.setInput(input)
scriptIntrinsicBlur.setRadius(radius.toFloat())
scriptIntrinsicBlur.forEach(output)
output.copyTo(toTransform)
renderScript.destroy()
return toTransform
Comment on lines +17 to +27

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

The rsBlur method uses RenderScript, which requires API level 17 or higher. Add an API level check to prevent crashes on older devices. You can use @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2) to indicate the minimum API level required and wrap the method body in an if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) check.

    @RequiresApi(Build.VERSION_CODES.JELLY_BEAN_MR2)
    fun rsBlur(context: Context?, toTransform: Bitmap, radius: Int): Bitmap {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN_MR2) {
            val renderScript = RenderScript.create(context)
            val input = Allocation.createFromBitmap(renderScript, toTransform)
            val output = Allocation.createTyped(renderScript, input.type)
            val scriptIntrinsicBlur = ScriptIntrinsicBlur.create(renderScript, Element.U8_4(renderScript))
            scriptIntrinsicBlur.setInput(input)
            scriptIntrinsicBlur.setRadius(radius.toFloat())
            scriptIntrinsicBlur.forEach(output)
            output.copyTo(toTransform)
            renderScript.destroy()
            return toTransform
        } else {
            // Fallback to a different blur method or return the original bitmap
            return toTransform
        }
    }

}

fun blur(toTransform: Bitmap, radius: Int): Bitmap? {
if (radius < 1) {
return null
}
val w = toTransform.width
val h = toTransform.height
val pix = IntArray(w * h)
toTransform.getPixels(pix, 0, w, 0, 0, w, h)
val wm = w - 1
val hm = h - 1
val wh = w * h
val div = radius + radius + 1
val r = IntArray(wh)
val g = IntArray(wh)
val b = IntArray(wh)
var rsum: Int
var gsum: Int
var bsum: Int
var x: Int
var y: Int
var i: Int
var p: Int
var yp: Int
var yi: Int
var yw: Int
val vmin = IntArray(Math.max(w, h))
var divsum = div + 1 shr 1
divsum *= divsum
val dv = IntArray(256 * divsum)
i = 0
while (i < 256 * divsum) {
dv[i] = i / divsum
i++
}
yi = 0
yw = yi
val stack = Array(div) { IntArray(3) }
var stackpointer: Int
var stackstart: Int
var sir: IntArray
var rbs: Int
val r1 = radius + 1
var routsum: Int
var goutsum: Int
var boutsum: Int
var rinsum: Int
var ginsum: Int
var binsum: Int
y = 0
while (y < h) {
bsum = 0
gsum = bsum
rsum = gsum
boutsum = rsum
goutsum = boutsum
routsum = goutsum
binsum = routsum
ginsum = binsum
rinsum = ginsum
i = -radius
while (i <= radius) {
p = pix[yi + Math.min(wm, Math.max(i, 0))]
sir = stack[i + radius]
sir[0] = p and 0xff0000 shr 16
sir[1] = p and 0x00ff00 shr 8
sir[2] = p and 0x0000ff
rbs = r1 - Math.abs(i)
rsum += sir[0] * rbs
gsum += sir[1] * rbs
bsum += sir[2] * rbs
if (i > 0) {
rinsum += sir[0]
ginsum += sir[1]
binsum += sir[2]
} else {
routsum += sir[0]
goutsum += sir[1]
boutsum += sir[2]
}
i++
}
stackpointer = radius
x = 0
while (x < w) {
r[yi] = dv[rsum]
g[yi] = dv[gsum]
b[yi] = dv[bsum]
rsum -= routsum
gsum -= goutsum
bsum -= boutsum
stackstart = stackpointer - radius + div
sir = stack[stackstart % div]
routsum -= sir[0]
goutsum -= sir[1]
boutsum -= sir[2]
if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm)
}
p = pix[yw + vmin[x]]
sir[0] = p and 0xff0000 shr 16
sir[1] = p and 0x00ff00 shr 8
sir[2] = p and 0x0000ff
rinsum += sir[0]
ginsum += sir[1]
binsum += sir[2]
rsum += rinsum
gsum += ginsum
bsum += binsum
stackpointer = (stackpointer + 1) % div
sir = stack[stackpointer % div]
routsum += sir[0]
goutsum += sir[1]
boutsum += sir[2]
rinsum -= sir[0]
ginsum -= sir[1]
binsum -= sir[2]
yi++
x++
}
yw += w
y++
}
x = 0
while (x < w) {
bsum = 0
gsum = bsum
rsum = gsum
boutsum = rsum
goutsum = boutsum
routsum = goutsum
binsum = routsum
ginsum = binsum
rinsum = ginsum
yp = -radius * w
i = -radius
while (i <= radius) {
yi = Math.max(0, yp) + x
sir = stack[i + radius]
sir[0] = r[yi]
sir[1] = g[yi]
sir[2] = b[yi]
rbs = r1 - Math.abs(i)
rsum += r[yi] * rbs
gsum += g[yi] * rbs
bsum += b[yi] * rbs
if (i > 0) {
rinsum += sir[0]
ginsum += sir[1]
binsum += sir[2]
} else {
routsum += sir[0]
goutsum += sir[1]
boutsum += sir[2]
}
if (i < hm) {
yp += w
}
i++
}
yi = x
stackpointer = radius
y = 0
while (y < h) {
pix[yi] = -0x1000000 and pix[yi] or (dv[rsum] shl 16) or (dv[gsum] shl 8) or dv[bsum]
rsum -= routsum
gsum -= goutsum
bsum -= boutsum
stackstart = stackpointer - radius + div
sir = stack[stackstart % div]
routsum -= sir[0]
goutsum -= sir[1]
boutsum -= sir[2]
if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * w
}
p = x + vmin[y]
sir[0] = r[p]
sir[1] = g[p]
sir[2] = b[p]
rinsum += sir[0]
ginsum += sir[1]
binsum += sir[2]
rsum += rinsum
gsum += ginsum
bsum += binsum
stackpointer = (stackpointer + 1) % div
sir = stack[stackpointer]
routsum += sir[0]
goutsum += sir[1]
boutsum += sir[2]
rinsum -= sir[0]
ginsum -= sir[1]
binsum -= sir[2]
yi += w
y++
}
x++
}
toTransform.setPixels(pix, 0, w, 0, 0, w, h)
return toTransform
}
Comment on lines +30 to +230

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

The blur method uses a box blur algorithm. While functional, it involves numerous integer array allocations (pix, r, g, b, vmin, dv, stack, sir). Consider exploring optimizations such as reusing arrays or using more efficient data structures to reduce memory overhead and improve performance. Also, consider using Kotlin's built-in array operations for better readability.

}
Loading