Skip to content

Commit 096d575

Browse files
author
Marco Romano
authored
Optimize use of blurhash algo in bloom modifier (#1509)
- Reduced to 20px the size of the bitmap we encode the blurhash from. - Reduced the blurhash components from 5 to 4. As per suggestions in: https://github.com/woltapp/blurhash#good-questions
1 parent f103b0a commit 096d575

File tree

33 files changed

+89
-77
lines changed

33 files changed

+89
-77
lines changed

libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/Bloom.kt

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -98,15 +98,14 @@ import androidx.compose.ui.unit.toSize
9898
import coil.imageLoader
9999
import coil.request.DefaultRequestOptions
100100
import coil.request.ImageRequest
101-
import coil.size.Size
102101
import com.airbnb.android.showkase.annotation.ShowkaseComposable
103102
import com.vanniktech.blurhash.BlurHash
104103
import io.element.android.libraries.designsystem.R
105104
import io.element.android.libraries.designsystem.colors.AvatarColorsProvider
106105
import io.element.android.libraries.designsystem.components.avatar.AvatarData
107-
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
108106
import io.element.android.libraries.designsystem.preview.ElementPreview
109107
import io.element.android.libraries.designsystem.preview.PreviewGroup
108+
import io.element.android.libraries.designsystem.preview.PreviewsDayNight
110109
import io.element.android.libraries.designsystem.text.toDp
111110
import io.element.android.libraries.designsystem.theme.components.Icon
112111
import io.element.android.libraries.designsystem.theme.components.MediumTopAppBar
@@ -129,7 +128,9 @@ object BloomDefaults {
129128
* Number of components to use with BlurHash to generate the blur effect.
130129
* Larger values mean more detailed blurs.
131130
*/
132-
const val HASH_COMPONENTS = 5
131+
const val HASH_COMPONENTS = 4
132+
const val ENCODE_SIZE_PX = 20
133+
const val DECODE_SIZE_PX = 5
133134

134135
/** Default bloom layers. */
135136
@Composable
@@ -189,7 +190,11 @@ fun Modifier.bloom(
189190
if (hash == null) return@composed this
190191

191192
val hashedBitmap = remember(hash) {
192-
BlurHash.decode(hash, BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS)?.asImageBitmap()
193+
BlurHash.decode(
194+
blurHash = hash,
195+
width = BloomDefaults.DECODE_SIZE_PX,
196+
height = BloomDefaults.DECODE_SIZE_PX,
197+
)?.asImageBitmap()
193198
} ?: return@composed this
194199
val density = LocalDensity.current
195200
val pixelSize = remember(blurSize, density) { blurSize.toIntSize(density) }
@@ -327,7 +332,6 @@ fun Modifier.avatarBloom(
327332

328333
// Request the avatar contents to use as the bloom source
329334
val context = LocalContext.current
330-
val density = LocalDensity.current
331335
if (avatarData.url != null) {
332336
val painterRequest = remember(avatarData) {
333337
ImageRequest.Builder(context)
@@ -337,7 +341,7 @@ fun Modifier.avatarBloom(
337341
// Needed to be able to read pixels from the Bitmap for the hash
338342
.allowHardware(false)
339343
// Reduce size so it loads faster for large avatars
340-
.size(with(density) { Size(64.dp.roundToPx(), 64.dp.roundToPx()) })
344+
.size(BloomDefaults.ENCODE_SIZE_PX, BloomDefaults.ENCODE_SIZE_PX)
341345
.build()
342346
}
343347

@@ -349,9 +353,9 @@ fun Modifier.avatarBloom(
349353
context.imageLoader.execute(painterRequest).drawable ?: return@withContext
350354
val bitmap = (drawable as? BitmapDrawable)?.bitmap ?: return@withContext
351355
blurHash = BlurHash.encode(
352-
bitmap,
353-
BloomDefaults.HASH_COMPONENTS,
354-
BloomDefaults.HASH_COMPONENTS
356+
bitmap = bitmap,
357+
componentX = BloomDefaults.HASH_COMPONENTS,
358+
componentY = BloomDefaults.HASH_COMPONENTS,
355359
)
356360
}
357361
}
@@ -371,14 +375,18 @@ fun Modifier.avatarBloom(
371375
// There is no URL so we'll generate an avatar with the initials and use that as the bloom source
372376
val avatarColors = AvatarColorsProvider.provide(avatarData.id, ElementTheme.isLightTheme)
373377
val initialsBitmap = initialsBitmap(
374-
width = avatarData.size.dp,
375-
height = avatarData.size.dp,
378+
width = BloomDefaults.ENCODE_SIZE_PX.toDp(),
379+
height = BloomDefaults.ENCODE_SIZE_PX.toDp(),
376380
text = avatarData.initial,
377381
textColor = avatarColors.foreground,
378382
backgroundColor = avatarColors.background,
379383
)
380384
val hash = remember(avatarData, avatarColors) {
381-
BlurHash.encode(initialsBitmap.asAndroidBitmap(), BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS)
385+
BlurHash.encode(
386+
bitmap = initialsBitmap.asAndroidBitmap(),
387+
componentX = BloomDefaults.HASH_COMPONENTS,
388+
componentY = BloomDefaults.HASH_COMPONENTS,
389+
)
382390
}
383391
bloom(
384392
hash = hash,
@@ -541,7 +549,11 @@ internal fun BloomInitialsPreview(@PreviewParameter(InitialsColorStateProvider::
541549
ElementPreview {
542550
val avatarColors = AvatarColorsProvider.provide("$color", ElementTheme.isLightTheme)
543551
val bitmap = initialsBitmap(text = "F", backgroundColor = avatarColors.background, textColor = avatarColors.foreground)
544-
val hash = BlurHash.encode(bitmap.asAndroidBitmap(), BloomDefaults.HASH_COMPONENTS, BloomDefaults.HASH_COMPONENTS)
552+
val hash = BlurHash.encode(
553+
bitmap = bitmap.asAndroidBitmap(),
554+
componentX = BloomDefaults.HASH_COMPONENTS,
555+
componentY = BloomDefaults.HASH_COMPONENTS,
556+
)
545557
Box(
546558
modifier = Modifier
547559
.size(256.dp)
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading
Loading

0 commit comments

Comments
 (0)