Floutage dans Compose

Les effets de flou adoucissent les détails visuels, créent une profondeur de champ photographique et attirent l'attention sur les éléments d'interface utilisateur au premier plan. Dans Jetpack Compose, utilisez Modifier.blur pour flouter le contenu dessiné dans un composable, y compris les images, les formes, le texte et les conteneurs de mise en page. L'application de Modifier.blur affiche le composable dans un calque graphique distinct.

À gauche : l'image d'origine. Au centre : l'image avec un flou uniforme appliqué sur toute la surface. À droite : l'image avec un flou progressif qui est net en haut et augmente vers le bas.
Figure 1. À gauche : l'image d'origine. Au centre : l'image avec un flou uniforme appliqué sur toute la surface. À droite : l'image avec un flou progressif qui est net en haut et augmente vers le bas.

En fonction de vos objectifs de conception, vous pouvez faire varier le flou de deux manières :

  • Flou uniforme : applique un rayon de flou constant sur l'ensemble du composable, de manière égale sur les deux axes ou avec des rayons horizontal et vertical indépendants (radiusX, radiusY).
  • Flou progressif : fait varier le rayon de flou dans l'espace sur le composable à l'aide de dégradés BlurRadiusSpec ou d'un Shader personnalisé.

Appliquer un floutage uniforme

Pour appliquer un flou constant sur l'ensemble d'un composable, transmettez un rayon Dp à Modifier.blur. Transmettez une seule valeur radius pour flouter le contenu de manière égale sur les axes horizontal (X) et vertical (Y) :

@Composable
fun UniformBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                radius = 8.dp,
                edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp)),
            ),
    )
}

Un chien flouté de manière uniforme sur les axes horizontal et vertical.
Figure 2. Chien flouté de manière uniforme sur les axes horizontal et vertical.

Pour créer un effet de flou directionnel, transmettez des valeurs radiusX et radiusY distinctes à Modifier.blur. radiusX et radiusY doivent être supérieurs à 0.dp pour que l'effet de flou s'applique, comme illustré dans l'exemple suivant :

@Composable
fun DirectionalBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                radiusX = 10.dp,
                radiusY = 2.dp,
                edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp)),
            ),
    )
}

Chien avec un effet de flou de mouvement horizontal prononcé.
Figure 3. Image carrée d'un chien avec un effet de flou de mouvement horizontal prononcé.

Appliquer un flou progressif

Un flou progressif fait varier le rayon de flou sur un composable, créant ainsi une transition fluide entre les zones nettes et floues.

Transmettez un BlurRadiusSpec à Modifier.blur. Par exemple, utilisez BlurRadiusSpec.verticalGradient avec startRadius = 0.dp et endRadius = 6.dp pour que le haut d'une image reste net tout en la floutant progressivement vers le bas, comme illustré dans l'exemple suivant :

@Composable
fun ProgressiveBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                // Sharp at the top (0.dp), progressively blurred toward the bottom (6.dp)
                blurRadiusSpec = BlurRadiusSpec.verticalGradient(
                    startRadius = 0.dp,
                    endRadius = 6.dp,
                ),
                edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp)),
            ),
    )
}

Un chien net en haut et qui devient progressivement flou vers le bas.
Figure 4. Image d'un chien nette en haut et qui devient progressivement floue vers le bas.

Spécifier des dégradés de flou avec BlurRadiusSpec

Dans BlurRadiusSpec, les mesures sont définies en Dp et s'ajustent automatiquement à la taille et à la densité d'affichage du calque lors du dessin. Les flous variant dans l'espace sont limités à 150 pixels une fois convertis, tandis que BlurRadiusSpec.uniform n'a pas de limite.

Le tableau suivant liste les fonctions d'usine disponibles sur BlurRadiusSpec :

Usine BlurRadiusSpec Description
BlurRadiusSpec.verticalGradient Modifie progressivement le rayon de flou verticalement, du haut (0f) vers le bas (1f) du calque.
BlurRadiusSpec.horizontalGradient Modifie progressivement le rayon de flou horizontalement, du bord gauche (0f) au bord droit (1f).
BlurRadiusSpec.linearGradient Applique une transition de flou directionnel le long d'une ligne droite reliant des coordonnées DpOffset spécifiques.
BlurRadiusSpec.radialGradient Diffuse le flou vers l'extérieur, d'un point focal vers la limite de fallOffRadius.
BlurRadiusSpec.uniform Applique un rayon de flou uniforme sur l'ensemble du calque.
BlurRadiusSpec.shader Utilise le canal alpha d'un Shader personnalisé pour contrôler et mettre à l'échelle le maxRadius au niveau de chaque pixel.

Personnaliser la distribution du flou avec BlurStop

Les flous de dégradé standards interpolent de manière linéaire entre 0f et 1f. Pour personnaliser la répartition du flou sur une surface (par exemple, pour flouter plusieurs bords ou garder une section centrale complètement nette), transmettez un List<BlurStop> contenant entre 2 et 16 entrées BlurStop à verticalGradient, horizontalGradient, linearGradient ou radialGradient. Définissez les éléments suivants pour chaque entrée BlurStop :

  • fraction : position relative le long du dégradé, de 0.0f à 1.0f. Les arrêts sont triés automatiquement par fraction.
  • radius : rayon de flou en Dp appliqué à cette position de fraction.

Par exemple, quatre points d'arrêt floutent les bords supérieur et inférieur d'une image tout en conservant une netteté parfaite au milieu, comme illustré dans l'exemple suivant :

@Composable
fun MultiStopBlurExample() {
    Image(
        painter = painterResource(id = R.drawable.dog),
        contentDescription = stringResource(id = R.string.dog_content_description),
        contentScale = ContentScale.Crop,
        modifier = Modifier
            .size(150.dp)
            .blur(
                // Blurred at the top and bottom edges, sharp in the middle (0.3f..0.7f)
                blurRadiusSpec = BlurRadiusSpec.verticalGradient(
                    stops = listOf(
                        BlurStop(fraction = 0.0f, radius = 20.dp),
                        BlurStop(fraction = 0.3f, radius = 0.dp),
                        BlurStop(fraction = 0.7f, radius = 0.dp),
                        BlurStop(fraction = 1.0f, radius = 20.dp),
                    ),
                ),
                edgeTreatment = BlurredEdgeTreatment.Unbounded,
            ),
    )
}

Un chien avec les bords supérieur et inférieur floutés, tandis que la bande horizontale centrale reste nette.
Figure 5 : Image d'un chien dont les bords supérieur et inférieur sont flous, tandis que la bande horizontale centrale est nette.

Configurer les propriétés d'une couche avec BlurScope

Au lieu de transmettre blurRadiusSpec directement, vous pouvez transmettre un bloc de configuration à Modifier.blur { ... }. Ce bloc s'exécute dans BlurScope, ce qui vous donne un accès direct à la densité de la mise en page et aux propriétés suivantes :

  • size: DpSize : largeur et hauteur mesurées de la couche floutée dans Dp, qui définit l'espace de coordonnées pour la géométrie du dégradé.
  • blurRadiusSpec: BlurRadiusSpec : configuration du rayon de flou sur la surface. La valeur par défaut est BlurRadiusSpec.uniform(0.dp) (pas de floutage).
  • edgeTreatment: BlurredEdgeTreatment : stratégie utilisée pour échantillonner et rogner les pixels en dehors des limites du contenu. La valeur par défaut est BlurredEdgeTreatment.Rectangle.
  • alpha: Float : opacité du calque flouté dans la plage 0f..1f. La valeur par défaut est 1f.

Comme le bloc BlurScope s'exécute pendant la phase de calque graphique, après la mesure et la mise en page, vous pouvez calculer la géométrie du dégradé à partir de size sans déclencher de recomposition.

Contrôler le rognage des bords avec BlurredEdgeTreatment

Étant donné que le floutage échantillonne les pixels voisins dans le rayon de floutage, la sortie floutée s'étend au-delà des limites du contenu d'origine en fonction du rayon de floutage. BlurredEdgeTreatment détermine la façon dont les pixels situés en dehors des limites d'origine sont échantillonnés et si le résultat est limité à une forme.

BlurredEdgeTreatment fonctionne avec les flous uniformes et progressifs :

BlurredEdgeTreatment Comportement Sortie
BlurredEdgeTreatment.Rectangle (par défaut) Rogne le résultat du floutage jusqu'aux limites rectangulaires du contenu d'origine et échantillonne les pixels de bordure les plus proches (TileMode.Clamp). Image floue d'un chien découpée selon une forme rectangulaire nette.
BlurredEdgeTreatment(shape) Limite le résultat du flou à la Shape spécifiée (par exemple, RoundedCornerShape(8.dp)) et échantillonne les pixels de bord les plus proches (TileMode.Clamp). Conserve la netteté du résultat flou à la limite de la forme sans déborder des limites d'origine. Image floue d'un chien découpée en forme de rectangle aux angles arrondis et aux bords nets.
BlurredEdgeTreatment.Unbounded Ne rogne pas le résultat du floutage (TileMode.Decal). Les pixels situés en dehors des limites du contenu échantillonnent du noir transparent, ce qui donne aux bords extérieurs de l'image un aspect flou et flouté au-delà des limites d'origine. Image floue d'un chien dont les bords s'estompent doucement au-delà des limites d'origine.

Pour découvrir comment ces API se combinent dans des modèles d'interface utilisateur complets, par exemple pour estomper les bords d'un contenu défilant, mettre en avant un point focal ou masquer un flou avec un nuanceur personnalisé, consultez Cas d'utilisation courants du flou.