[Android] Use RenderEffect instead of RenderScript on API 31+
Nicolas Pomepuy
git at videolan.org
Tue Nov 15 12:44:35 UTC 2022
vlc-android | branch: master | Nicolas Pomepuy <nicolas at videolabs.io> | Tue Nov 15 08:50:33 2022 +0100| [0f231358dc92c80e03fc0174ad5badcc373df1ae] | committer: Duncan McNamara
Use RenderEffect instead of RenderScript on API 31+
> https://code.videolan.org/videolan/vlc-android/commit/0f231358dc92c80e03fc0174ad5badcc373df1ae
---
.../ui/audioplayer/AudioPlayerActivity.kt | 4 +--
.../videolan/vlc/gui/HeaderMediaListActivity.kt | 6 +---
.../videolan/vlc/gui/audio/AudioPlayerAnimator.kt | 11 ++-----
.../src/org/videolan/vlc/gui/helpers/UiTools.kt | 36 ++++++++++++++++++++++
4 files changed, 41 insertions(+), 16 deletions(-)
diff --git a/application/television/src/main/java/org/videolan/television/ui/audioplayer/AudioPlayerActivity.kt b/application/television/src/main/java/org/videolan/television/ui/audioplayer/AudioPlayerActivity.kt
index 0cb8d47353..1d385c61c0 100644
--- a/application/television/src/main/java/org/videolan/television/ui/audioplayer/AudioPlayerActivity.kt
+++ b/application/television/src/main/java/org/videolan/television/ui/audioplayer/AudioPlayerActivity.kt
@@ -208,15 +208,13 @@ class AudioPlayerActivity : BaseTvActivity(),KeycodeListener {
private fun updateBackground() = lifecycleScope.launchWhenStarted {
val width = if (binding.albumCover.width > 0) binding.albumCover.width else this at AudioPlayerActivity.getScreenWidth()
val cover = withContext(Dispatchers.IO) { AudioUtil.readCoverBitmap(Uri.decode(currentCoverArt), width) }
- val blurredCover = if (cover != null) withContext(Dispatchers.Default) { UiTools.blurBitmap(cover) } else null
if (cover == null) {
binding.albumCover.setImageResource(R.drawable.ic_no_artwork_big)
binding.background.clearColorFilter()
binding.background.setImageResource(0)
} else {
+ UiTools.blurView(binding.background, cover, 15F, UiTools.getColorFromAttribute(binding.background.context, R.attr.audio_player_background_tint))
binding.albumCover.setImageBitmap(cover)
- binding.background.setColorFilter(UiTools.getColorFromAttribute(binding.background.context, R.attr.audio_player_background_tint))
- binding.background.setImageBitmap(blurredCover)
}
}
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt b/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt
index 3c5636e102..d36bdf33ce 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/HeaderMediaListActivity.kt
@@ -171,11 +171,7 @@ open class HeaderMediaListActivity : AudioPlayerContainerActivity(), IEventsHand
binding.cover = BitmapDrawable(this at HeaderMediaListActivity.resources, cover)
binding.appbar.setExpanded(true, true)
val radius = if (isPlaylist) 25f else 15f
- val blurredCover = UiTools.blurBitmap(cover, radius)
- withContext(Dispatchers.Main) {
- binding.backgroundView.setColorFilter(UiTools.getColorFromAttribute(context, R.attr.audio_player_background_tint))
- binding.backgroundView.setImageBitmap(blurredCover)
- }
+ UiTools.blurView(binding.backgroundView, cover, radius, UiTools.getColorFromAttribute(context, R.attr.audio_player_background_tint))
}
}
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerAnimator.kt b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerAnimator.kt
index ebd53a98e6..11385f76dc 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerAnimator.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/audio/AudioPlayerAnimator.kt
@@ -214,7 +214,6 @@ internal class AudioPlayerAnimator : IAudioPlayerAnimator, LifecycleObserver {
/**
* Updates the player background with or without a blurred cover depending on the user setting
*/
- @TargetApi(Build.VERSION_CODES.JELLY_BEAN_MR1)
override suspend fun updateBackground() {
if (Settings.getInstance(audioPlayer.requireActivity()).getBoolean("blurred_cover_background", true)) {
val mw = audioPlayer.playlistModel.currentMediaWrapper ?: return
@@ -223,13 +222,9 @@ internal class AudioPlayerAnimator : IAudioPlayerAnimator, LifecycleObserver {
if (mw.artworkMrl.isNullOrEmpty()) setDefaultBackground()
else {
val width = if (binding.contentLayout.width > 0) binding.contentLayout.width else audioPlayer.activity?.getScreenWidth() ?: return
- val blurredCover = withContext(Dispatchers.IO) { UiTools.blurBitmap(AudioUtil.readCoverBitmap(Uri.decode(mw.artworkMrl), width)) }
- if (blurredCover !== null) {
- val activity = audioPlayer.activity as? AudioPlayerContainerActivity ?: return
- binding.backgroundView.setColorFilter(UiTools.getColorFromAttribute(activity, R.attr.audio_player_background_tint))
- binding.backgroundView.setImageBitmap(blurredCover)
- binding.backgroundView.visibility = View.VISIBLE
- } else setDefaultBackground()
+ val activity = audioPlayer.activity as? AudioPlayerContainerActivity ?: return
+ val bitmap = AudioUtil.readCoverBitmap(Uri.decode(mw.artworkMrl), width)
+ bitmap?.let { UiTools.blurView(binding.backgroundView, bitmap, 15F, UiTools.getColorFromAttribute(activity, R.attr.audio_player_background_tint)) } ?: setDefaultBackground()
}
} else {
currentCoverArt = null
diff --git a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
index e686e9bac6..9259f2d915 100644
--- a/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
+++ b/application/vlc-android/src/org/videolan/vlc/gui/helpers/UiTools.kt
@@ -31,6 +31,8 @@ import android.content.Context
import android.content.DialogInterface
import android.content.Intent
import android.graphics.Bitmap
+import android.graphics.RenderEffect
+import android.graphics.Shader
import android.graphics.drawable.BitmapDrawable
import android.media.MediaRouter
import android.os.Build
@@ -540,6 +542,40 @@ object UiTools {
}
}
+ /**
+ * Set a blur effect on the whole [ImageView] using [RenderEffect]
+ * with a fallback on [RenderScript] if needed
+ *
+ * @param imageView the [ImageView] to blur
+ * @param bitmap the [Bitmap] to display
+ * @param radius the blur radius
+ * @param colorFilter the color filter to be used on the view depending on the theme
+ */
+ suspend fun blurView(imageView: ImageView, bitmap: Bitmap?, radius: Float, colorFilter: Int) {
+ imageView.setColorFilter(colorFilter)
+ if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.S) {
+ val blur = RenderEffect.createBlurEffect(radius, radius, Shader.TileMode.CLAMP)
+ imageView.setRenderEffect(blur)
+ imageView.setImageBitmap(bitmap)
+ } else {
+ val blurred = withContext(Dispatchers.IO) {
+ blurBitmap(bitmap, radius)
+ }
+ withContext(Dispatchers.Main) {
+ imageView.setImageBitmap(blurred)
+ }
+ }
+ }
+
+ /**
+ * Blur a [Bitmap]. it uses a deprecated API and therefore should not be used
+ * except for a fallback for API < 31
+ *
+ * @param bitmap the [Bitmap] to blur
+ * @param radius the bur radius
+ * @return a blurred bitmap
+ */
+ @Suppress("DEPRECATION")
@JvmOverloads
fun blurBitmap(bitmap: Bitmap?, radius: Float = 15.0f): Bitmap? {
if (bitmap == null || bitmap.config == null) return null
More information about the Android
mailing list