Skip to content

Commit

Permalink
add TBlurView.
Browse files Browse the repository at this point in the history
  • Loading branch information
Tamsiree committed Mar 26, 2020
1 parent e2bf4a5 commit 8d74f34
Show file tree
Hide file tree
Showing 6 changed files with 138 additions and 62 deletions.
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
package com.tamsiree.rxdemo.activity

import android.graphics.BitmapFactory
import android.os.Bundle
import androidx.recyclerview.widget.LinearLayoutManager
import com.tamsiree.rxdemo.R
import com.tamsiree.rxdemo.adapter.AdapterCardGallery
import com.tamsiree.rxkit.RxAnimationTool
import com.tamsiree.rxkit.TBlurTool
import com.tamsiree.rxkit.interfaces.OnDoIntListener
import com.tamsiree.rxkit.view.RxToast
import com.tamsiree.rxui.activity.ActivityBase
Expand Down Expand Up @@ -53,13 +50,9 @@ class ActivityTCardGallery : ActivityBase() {
RxToast.normal("选中$intValue")
if (mLastPos == intValue) {
return
} else if (mLastPos > intValue) {
// tIndicator.moveToLeft()
} else if (mLastPos < intValue) {
// tIndicator.moveToRight()
}
mLastPos = intValue
notifyBackgroundChange()
blurView.notifyChange(mList[mLastPos])
}
})
}
Expand All @@ -72,14 +65,4 @@ class ActivityTCardGallery : ActivityBase() {
recyclerView.adapter?.notifyDataSetChanged()
}

private fun notifyBackgroundChange() {
val resId = mList[mLastPos]
blurView?.removeCallbacks(mBlurRunnable)
mBlurRunnable = Runnable {
val bitmap = BitmapFactory.decodeResource(resources, resId)
RxAnimationTool.startSwitchBackgroundAnim(blurView, TBlurTool.getBlurBitmap(blurView?.context, bitmap, 15))
}
blurView?.postDelayed(mBlurRunnable, 300)
}

}
11 changes: 6 additions & 5 deletions RxDemo/src/main/res/layout/activity_tcard_grallery.xml
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,13 @@
android:orientation="vertical"
tools:context=".activity.ActivityTCardGallery">

<ImageView
<com.tamsiree.rxui.view.TBlurView
android:id="@+id/blurView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#3f000000"
android:scaleType="centerCrop" />
app:blurDelayTime="100"
app:blurRadius="15"
app:blurSrc="@drawable/bg_friend" />

<com.tamsiree.rxui.view.tcardgralleryview.TCardGalleryView
android:id="@+id/recyclerView"
Expand Down Expand Up @@ -53,11 +54,11 @@
android:layout_height="wrap_content"
android:visibility="visible"
app:dotColor="@color/colorPrimaryDark"
app:selectedDotColor="@color/colorPrimary"
tools:background="@color/colorPrimary" />
app:selectedDotColor="@color/colorPrimary" />

</LinearLayout>


</RelativeLayout>

</LinearLayout>
4 changes: 2 additions & 2 deletions RxKit/src/main/java/com/tamsiree/rxkit/RxAnimationTool.kt
Original file line number Diff line number Diff line change
Expand Up @@ -272,14 +272,14 @@ object RxAnimationTool {
oldBitmapDrawable = ColorDrawable(-0x3d3d3e)
}
if (oldTransitionDrawable == null) {
oldTransitionDrawable = TransitionDrawable(arrayOf(oldBitmapDrawable, BitmapDrawable(bitmap)))
oldTransitionDrawable = TransitionDrawable(arrayOf(oldBitmapDrawable, BitmapDrawable(RxTool.getContext().resources, bitmap)))
oldTransitionDrawable.setId(0, 0)
oldTransitionDrawable.setId(1, 1)
oldTransitionDrawable.isCrossFadeEnabled = true
view.setImageDrawable(oldTransitionDrawable)
} else {
oldTransitionDrawable.setDrawableByLayerId(oldTransitionDrawable.getId(0), oldBitmapDrawable)
oldTransitionDrawable.setDrawableByLayerId(oldTransitionDrawable.getId(1), BitmapDrawable(bitmap))
oldTransitionDrawable.setDrawableByLayerId(oldTransitionDrawable.getId(1), BitmapDrawable(RxTool.getContext().resources, bitmap))
}
oldTransitionDrawable.startTransition(1000)
}
Expand Down
65 changes: 28 additions & 37 deletions RxKit/src/main/java/com/tamsiree/rxkit/TBlurTool.kt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,9 @@ import android.renderscript.RenderScript.RSMessageHandler
import android.renderscript.ScriptIntrinsicBlur
import android.widget.ImageView
import com.tamsiree.rxkit.RxImageTool.isEmptyBitmap
import kotlin.math.abs
import kotlin.math.max
import kotlin.math.min

/**
* RenderScript图片高斯模糊
Expand All @@ -20,34 +23,33 @@ object TBlurTool {
/**
* 建议模糊度(在0.0到25.0之间)
*/
private const val BLUR_RADIUS = 20
private const val BLUR_RADIUS = 20f
private const val SCALED_WIDTH = 100
private const val SCALED_HEIGHT = 100

@JvmOverloads
@JvmStatic
fun blur(imageView: ImageView, bitmap: Bitmap?, radius: Int = BLUR_RADIUS) {
fun blur(imageView: ImageView, bitmap: Bitmap, radius: Float = BLUR_RADIUS) {
imageView.setImageBitmap(getBlurBitmap(imageView.context, bitmap, radius))
}

@JvmStatic
fun getBlurBitmap(context: Context?, bitmap: Bitmap?): Bitmap {
fun getBlurBitmap(context: Context, bitmap: Bitmap): Bitmap {
return getBlurBitmap(context, bitmap, BLUR_RADIUS)
}

/**
* 得到模糊后的bitmap
* thanks http://wl9739.github.io/2016/07/14/教你一分钟实现模糊效果/
*
* @param context
* @param bitmap
* @param radius
* @return
*/
@JvmStatic
fun getBlurBitmap(context: Context?, bitmap: Bitmap?, radius: Int): Bitmap {
fun getBlurBitmap(context: Context, bitmap: Bitmap, radius: Float): Bitmap {
// 将缩小后的图片做为预渲染的图片。
val inputBitmap = Bitmap.createScaledBitmap(bitmap!!, SCALED_WIDTH, SCALED_HEIGHT, false)
val inputBitmap = Bitmap.createScaledBitmap(bitmap, SCALED_WIDTH, SCALED_HEIGHT, false)
// 创建一张渲染后的输出图片。
val outputBitmap = Bitmap.createBitmap(inputBitmap)

Expand All @@ -62,7 +64,7 @@ object TBlurTool {
val tmpOut = Allocation.createFromBitmap(rs, outputBitmap)

// 设置渲染的模糊程度, 25f是最大模糊度
blurScript.setRadius(radius.toFloat())
blurScript.setRadius(radius)
// 设置blurScript对象的输入内存
blurScript.setInput(tmpIn)
// 将输出数据保存到输出内存中
Expand All @@ -72,17 +74,7 @@ object TBlurTool {
tmpOut.copyTo(outputBitmap)
return outputBitmap
}
/**
* 快速模糊
*
* 先缩小原图,对小图进行模糊,再放大回原先尺寸
*
* @param src 源图片
* @param scale 缩小倍数(0...1)
* @param radius 模糊半径
* @param recycle 是否回收
* @return 模糊后的图片
*/

/**
* 快速模糊
*
Expand Down Expand Up @@ -139,8 +131,8 @@ object TBlurTool {
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
@JvmStatic
fun renderScriptBlur(src: Bitmap?, radius: Float): Bitmap? {
var radius = radius
fun renderScriptBlur(src: Bitmap, radius: Float): Bitmap? {
var mRadius = radius
if (isEmptyBitmap(src)) return null
var rs: RenderScript? = null
try {
Expand All @@ -149,13 +141,13 @@ object TBlurTool {
val input = Allocation.createFromBitmap(rs, src, Allocation.MipmapControl.MIPMAP_NONE, Allocation.USAGE_SCRIPT)
val output = Allocation.createTyped(rs, input.type)
val blurScript = ScriptIntrinsicBlur.create(rs, Element.U8_4(rs))
if (radius > 25) {
radius = 25.0f
} else if (radius <= 0) {
radius = 1.0f
if (mRadius > 25) {
mRadius = 25.0f
} else if (mRadius <= 0) {
mRadius = 1.0f
}
blurScript.setInput(input)
blurScript.setRadius(radius)
blurScript.setRadius(mRadius)
blurScript.forEach(output)
output.copyTo(src)
} finally {
Expand All @@ -173,17 +165,16 @@ object TBlurTool {
* @return stackBlur模糊图片
*/
@JvmStatic
fun stackBlur(src: Bitmap?, radius: Int, recycle: Boolean): Bitmap? {
val ret: Bitmap?
ret = if (recycle) {
fun stackBlur(src: Bitmap, radius: Int, recycle: Boolean): Bitmap? {
val ret: Bitmap = if (recycle) {
src
} else {
src!!.copy(src.config, true)
src.copy(src.config, true)
}
if (radius < 1) {
return null
}
val w = ret!!.width
val w = ret.width
val h = ret.height
val pix = IntArray(w * h)
ret.getPixels(pix, 0, w, 0, 0, w, h)
Expand All @@ -204,7 +195,7 @@ object TBlurTool {
var yp: Int
var yi: Int
var yw: Int
val vmin = IntArray(Math.max(w, h))
val vmin = IntArray(max(w, h))
var divsum = div + 1 shr 1
divsum *= divsum
val dv = IntArray(256 * divsum)
Expand Down Expand Up @@ -240,12 +231,12 @@ object TBlurTool {
rinsum = ginsum
i = -radius
while (i <= radius) {
p = pix[yi + Math.min(wm, Math.max(i, 0))]
p = pix[yi + min(wm, 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)
rbs = r1 - abs(i)
rsum += sir[0] * rbs
gsum += sir[1] * rbs
bsum += sir[2] * rbs
Expand Down Expand Up @@ -275,7 +266,7 @@ object TBlurTool {
goutsum -= sir[1]
boutsum -= sir[2]
if (y == 0) {
vmin[x] = Math.min(x + radius + 1, wm)
vmin[x] = min(x + radius + 1, wm)
}
p = pix[yw + vmin[x]]
sir[0] = p and 0xff0000 shr 16
Expand Down Expand Up @@ -315,12 +306,12 @@ object TBlurTool {
yp = -radius * w
i = -radius
while (i <= radius) {
yi = Math.max(0, yp) + x
yi = 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)
rbs = r1 - abs(i)
rsum += r[yi] * rbs
gsum += g[yi] * rbs
bsum += b[yi] * rbs
Expand Down Expand Up @@ -354,7 +345,7 @@ object TBlurTool {
goutsum -= sir[1]
boutsum -= sir[2]
if (x == 0) {
vmin[y] = Math.min(y + r1, hm) * w
vmin[y] = min(y + r1, hm) * w
}
p = x + vmin[y]
sir[0] = r[p]
Expand Down
94 changes: 94 additions & 0 deletions RxUI/src/main/java/com/tamsiree/rxui/view/TBlurView.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
package com.tamsiree.rxui.view

import android.annotation.SuppressLint
import android.content.Context
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.util.AttributeSet
import android.widget.ImageView
import androidx.annotation.IntRange
import androidx.appcompat.widget.AppCompatImageView
import com.tamsiree.rxkit.RxAnimationTool.startSwitchBackgroundAnim
import com.tamsiree.rxkit.TBlurTool
import com.tamsiree.rxkit.TBlurTool.getBlurBitmap
import com.tamsiree.rxui.R

/**
* @ClassName TBlurImageView
* @Description TODO
* @Author tamsiree
* @Date 20-3-26 下午2:32
* @Version 1.0
*/
class TBlurView : AppCompatImageView {
private lateinit var mImageView: ImageView
private var mBlurRunnable: Runnable? = null

/**
* 模糊度 (0...25f)
*/
@SuppressLint("SupportAnnotationUsage")
@IntRange(from = 0, to = 25)
var blurRadius = 15f

//模糊View引用的资源ID
var blurSrc = 0

/**
* 单位是 ms 毫秒
*/
var delayTime: Long = 200
private lateinit var mContext: Context

constructor(context: Context) : super(context) {
initView(context, null)
}

constructor(context: Context, attrs: AttributeSet?) : super(context, attrs) {
initView(context, attrs)
}

constructor(context: Context, attrs: AttributeSet?, defStyleAttr: Int) : super(context, attrs, defStyleAttr) {
initView(context, attrs)
}

private fun initView(context: Context, attrs: AttributeSet?) {
mContext = context
mImageView = this
mImageView.scaleType = ScaleType.CENTER_CROP
//获得这个控件对应的属性。
val a = context.obtainStyledAttributes(attrs, R.styleable.TBlurView)
try {
//模糊View
blurSrc = a.getResourceId(R.styleable.TBlurView_blurSrc, R.drawable.icon_placeholder)
blurRadius = a.getInteger(R.styleable.TBlurView_blurRadius, 15).toFloat()
delayTime = a.getInteger(R.styleable.TBlurView_blurDelayTime, 200).toLong()
} finally {
//回收这个对象
a.recycle()
}
if (isInEditMode) {
val bitmap = BitmapFactory.decodeResource(mContext.resources, blurSrc)
mImageView.setImageBitmap(TBlurTool.stackBlur(bitmap, blurRadius.toInt(), true))
} else {
notifyChange(blurSrc)
}
}

fun notifyChange(resId: Int) {
blurSrc = resId
removeCallbacks(mBlurRunnable)
mBlurRunnable = Runnable { setBlurImage() }
postDelayed(mBlurRunnable, delayTime)
}

private fun generateBlurImage(): Bitmap {
val bitmap = BitmapFactory.decodeResource(mContext.resources, blurSrc)
return getBlurBitmap(mContext, bitmap, blurRadius)
}

private fun setBlurImage() {
startSwitchBackgroundAnim(mImageView, generateBlurImage())
}

}
7 changes: 7 additions & 0 deletions RxUI/src/main/res/values/attrs.xml
Original file line number Diff line number Diff line change
Expand Up @@ -636,4 +636,11 @@
<attr name="TLoadingColor" format="color" />
</declare-styleable>

<declare-styleable name="TBlurView">
<attr name="blurSrc" format="reference" />
<!-- 设置显示器动画时间-->
<attr name="blurDelayTime" format="integer" />
<attr name="blurRadius" format="integer" />
</declare-styleable>

</resources>

0 comments on commit 8d74f34

Please sign in to comment.