-
Notifications
You must be signed in to change notification settings - Fork 9
Create BlurUtils.kt #9
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
package me.bzcoder.easyglide.util | ||
|
||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
|
||
/** | ||
* @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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The @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
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The |
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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 likeme.bzcoder.webview.utils
to better reflect its purpose.