87 lines
3.6 KiB
Kotlin
87 lines
3.6 KiB
Kotlin
package com.tommasoberlose.anotherwidget.helpers
|
|
|
|
import android.content.Context
|
|
import android.graphics.*
|
|
import android.renderscript.*
|
|
import android.util.TypedValue
|
|
import android.widget.ImageView
|
|
import androidx.core.graphics.drawable.toBitmap
|
|
import com.tommasoberlose.anotherwidget.utils.isDarkTheme
|
|
import java.util.prefs.Preferences
|
|
import kotlin.math.min
|
|
|
|
object ImageHelper {
|
|
fun ImageView.applyShadow(originalView: ImageView, factor: Float = 1f) {
|
|
clearColorFilter()
|
|
val cElevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, when (if (context.isDarkTheme()) com.tommasoberlose.anotherwidget.global.Preferences.textShadowDark else com.tommasoberlose.anotherwidget.global.Preferences.textShadow) {
|
|
0 -> 0f * factor
|
|
1 -> 8f * factor
|
|
2 -> 16f * factor
|
|
else -> 0f * factor
|
|
}, resources.displayMetrics)
|
|
|
|
if (originalView.drawable != null && originalView.drawable.intrinsicWidth > 0 && originalView.drawable.intrinsicHeight > 0) {
|
|
val btm = originalView.drawable.toBitmap().copy(Bitmap.Config.ARGB_8888, true)
|
|
val comb = Bitmap.createBitmap(btm)
|
|
val shadowBitmap = generateShadowBitmap(context, cElevation, btm, factor)
|
|
|
|
shadowBitmap?.let {
|
|
val canvas = Canvas(comb)
|
|
canvas.drawColor(Color.TRANSPARENT)
|
|
canvas.save()
|
|
val rect = Rect()
|
|
// val bounds = originalView.drawable.copyBounds()
|
|
canvas.getClipBounds(rect)
|
|
rect.inset(-2 * getBlurRadius(context, cElevation).toInt(), -2 * getBlurRadius(context, cElevation).toInt())
|
|
canvas.save()
|
|
canvas.clipRect(rect)
|
|
canvas.drawBitmap(shadowBitmap, 0f, 2f, null)
|
|
canvas.restore()
|
|
setImageBitmap(comb)
|
|
}
|
|
}
|
|
}
|
|
|
|
private fun generateShadowBitmap(context: Context, cElevation: Float, bitmap: Bitmap?, factor: Float): Bitmap? {
|
|
val rs: RenderScript = RenderScript.create(context)
|
|
val element = Element.U8_4(rs)
|
|
val blurScript: ScriptIntrinsicBlur = ScriptIntrinsicBlur.create(rs, element)
|
|
val colorMatrixScript: ScriptIntrinsicColorMatrix = ScriptIntrinsicColorMatrix.create(rs)
|
|
val allocationIn = Allocation.createFromBitmap(rs, bitmap)
|
|
val allocationOut = Allocation.createTyped(rs, allocationIn.type)
|
|
|
|
val matrix = Matrix4f(floatArrayOf(
|
|
0f, 0f, 0f, 0f,
|
|
0f, 0f, 0f, 0f,
|
|
0f, 0f, 0f, 0f,
|
|
0f, 0f, 0f, when (if (context.isDarkTheme()) com.tommasoberlose.anotherwidget.global.Preferences.textShadowDark else com.tommasoberlose.anotherwidget.global.Preferences.textShadow) {
|
|
0 -> 0f * factor
|
|
1 -> 0.8f * factor
|
|
2 -> 1f * factor
|
|
else -> 0f
|
|
}))
|
|
|
|
colorMatrixScript.setColorMatrix(matrix)
|
|
colorMatrixScript.forEach(allocationIn, allocationOut)
|
|
|
|
blurScript.setRadius(getBlurRadius(context, cElevation))
|
|
|
|
blurScript.setInput(allocationOut)
|
|
blurScript.forEach(allocationIn)
|
|
|
|
allocationIn.copyTo(bitmap)
|
|
|
|
allocationIn.destroy()
|
|
allocationOut.destroy()
|
|
colorMatrixScript.destroy()
|
|
blurScript.destroy()
|
|
//rs.destroy()
|
|
|
|
return bitmap
|
|
}
|
|
|
|
private fun getBlurRadius(context: Context, customElevation: Float): Float {
|
|
val maxElevation = TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, 24f, context.resources.displayMetrics)
|
|
return min(25f * (customElevation / maxElevation), 25f)
|
|
}
|
|
} |