diff --git a/app/src/main/java/me/bzcoder/webview/utils/BlurUtils.kt b/app/src/main/java/me/bzcoder/webview/utils/BlurUtils.kt new file mode 100644 index 0000000..aeab5e3 --- /dev/null +++ b/app/src/main/java/me/bzcoder/webview/utils/BlurUtils.kt @@ -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 + +/** + * @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 + } + + 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 + } +}