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)
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading
Lines changed: 2 additions & 2 deletions
Loading

0 commit comments

Comments
 (0)