Android开发Glide做毛玻璃效果
其实毛玻璃效果,服务器端也可以在图片上加。
客户端做的示例代码:
import android.graphics.Bitmap
import android.graphics.Matriximport com.bumptech.glide.load.Key
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
import com.yiban1314.yiban.BuildConfigimport java.security.MessageDigest/*** 描述:使用 RenderScript 模糊图片*/
class BlurTransformation : BitmapTransformation() {private val id = "${BuildConfig.APPLICATION_ID}.glide.BlurTransformation"override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap {val blurBitmap = stackBlurBitmap(toTransform, 15, 10, false)return blurBitmap!!}override fun updateDiskCacheKey(messageDigest: MessageDigest) {messageDigest.update(id.toByteArray(Key.CHARSET))}private fun compressBitmapByScale(bitmap: Bitmap, scale: Int): Bitmap {// 使用矩阵进行压缩图片val matrix = Matrix()val s = 1.toFloat() / scalematrix.postScale(s, s)return Bitmap.createBitmap(bitmap, 0, 0, bitmap.width, bitmap.height, matrix, true)}private fun stackBlurBitmap(sentBitmap: Bitmap, scale: Int, radius: Int, reuse: Boolean): Bitmap? {// 创建一个新的压缩过的 Bitmapval overlay: Bitmap = compressBitmapByScale(sentBitmap, scale)val bitmap: Bitmapbitmap = if (reuse) {overlay} else {overlay.copy(overlay.config!!, true)}if (radius < 1) {return null}val w = bitmap.widthval h = bitmap.heightval pix = IntArray(w * h)bitmap.getPixels(pix, 0, w, 0, 0, w, h)val wm = w - 1val hm = h - 1val wh = w * hval div = radius + radius + 1val r = IntArray(wh)val g = IntArray(wh)val b = IntArray(wh)var rsum: Intvar gsum: Intvar bsum: Intvar x: Intvar y: Intvar i: Intvar p: Intvar yp: Intvar yi: Intvar yw: Intval vmin = IntArray(Math.max(w, h))var divsum = div + 1 shr 1divsum *= divsumval dv = IntArray(256 * divsum)i = 0while (i < 256 * divsum) {dv[i] = i / divsumi++}yi = 0yw = yival stack = Array(div) { IntArray(3) }var stackpointer: Intvar stackstart: Intvar sir: IntArrayvar rbs: Intval r1 = radius + 1var routsum: Intvar goutsum: Intvar boutsum: Intvar rinsum: Intvar ginsum: Intvar binsum: Inty = 0while (y < h) {bsum = 0gsum = bsumrsum = gsumboutsum = rsumgoutsum = boutsumroutsum = goutsumbinsum = routsumginsum = binsumrinsum = ginsumi = -radiuswhile (i <= radius) {p = pix[yi + Math.min(wm, Math.max(i, 0))]sir = stack[i + radius]sir[0] = p and 0xff0000 shr 16sir[1] = p and 0x00ff00 shr 8sir[2] = p and 0x0000ffrbs = r1 - Math.abs(i)rsum += sir[0] * rbsgsum += sir[1] * rbsbsum += sir[2] * rbsif (i > 0) {rinsum += sir[0]ginsum += sir[1]binsum += sir[2]} else {routsum += sir[0]goutsum += sir[1]boutsum += sir[2]}i++}stackpointer = radiusx = 0while (x < w) {r[yi] = dv[rsum]g[yi] = dv[gsum]b[yi] = dv[bsum]rsum -= routsumgsum -= goutsumbsum -= boutsumstackstart = stackpointer - radius + divsir = 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 16sir[1] = p and 0x00ff00 shr 8sir[2] = p and 0x0000ffrinsum += sir[0]ginsum += sir[1]binsum += sir[2]rsum += rinsumgsum += ginsumbsum += binsumstackpointer = (stackpointer + 1) % divsir = stack[stackpointer % div]routsum += sir[0]goutsum += sir[1]boutsum += sir[2]rinsum -= sir[0]ginsum -= sir[1]binsum -= sir[2]yi++x++}yw += wy++}x = 0while (x < w) {bsum = 0gsum = bsumrsum = gsumboutsum = rsumgoutsum = boutsumroutsum = goutsumbinsum = routsumginsum = binsumrinsum = ginsumyp = -radius * wi = -radiuswhile (i <= radius) {yi = Math.max(0, yp) + xsir = stack[i + radius]sir[0] = r[yi]sir[1] = g[yi]sir[2] = b[yi]rbs = r1 - Math.abs(i)rsum += r[yi] * rbsgsum += g[yi] * rbsbsum += b[yi] * rbsif (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 = xstackpointer = radiusy = 0while (y < h) {// Preserve alpha channel: ( 0xff000000 & pix[yi] )pix[yi] = -0x1000000 and pix[yi] or (dv[rsum] shl 16) or (dv[gsum] shl 8) or dv[bsum]rsum -= routsumgsum -= goutsumbsum -= boutsumstackstart = stackpointer - radius + divsir = 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 += rinsumgsum += ginsumbsum += binsumstackpointer = (stackpointer + 1) % divsir = stack[stackpointer]routsum += sir[0]goutsum += sir[1]boutsum += sir[2]rinsum -= sir[0]ginsum -= sir[1]binsum -= sir[2]yi += wy++}x++}bitmap.setPixels(pix, 0, w, 0, 0, w, h)return bitmap}
}
使用示例:
val requestOptions = RequestOptions()
requestOptions.transform(BlurTransformation())
Glide.with(MyApplication.getInstance().applicationContext).load("url").apply(requestOptions).into(imageView)