Unkenntlichmachung in „Compose“

Weichzeichner-Effekte machen visuelle Details weicher, erzeugen fotografische Tiefenschärfe und lenken den Fokus auf UI-Elemente im Vordergrund. In Jetpack Compose können Sie mit Modifier.blur den Inhalt einer komponierbaren Funktion weichzeichnen, einschließlich Bildern, Formen, Text und Layoutcontainern. Wenn Sie Modifier.blur anwenden, wird die zusammensetzbare Funktion in einer separaten Grafikebene gerendert.

Links: das Originalbild. Mitte: Das Bild mit einer gleichmäßigen Unschärfe über die gesamte Oberfläche. Rechts: Das Bild mit einer progressiven Unschärfe, die oben scharf ist und nach unten hin zunimmt.
Abbildung 1. Links: das Originalbild. Mitte: Das Bild mit einer gleichmäßigen Unschärfe, die auf die gesamte Oberfläche angewendet wurde. Rechts: das Bild mit einer progressiven Unschärfe, die oben scharf ist und nach unten hin zunimmt.

Je nach Ihren Designzielen können Sie die Unschärfe auf zwei Arten variieren:

  • Gleichmäßige Unschärfe: Wendet einen konstanten Unschärferadius auf das gesamte Compose-Element an, entweder gleichmäßig auf beiden Achsen oder mit unabhängigen horizontalen und vertikalen Radien (radiusX, radiusY).
  • Progressive Unschärfe: Der Unschärferadius wird räumlich über das Composable hinweg variiert, wobei BlurRadiusSpec-Verläufe oder ein benutzerdefiniertes Shader verwendet werden.

Gleichmäßige Unschärfe anwenden

Wenn Sie eine gleichmäßige Unschärfe auf eine ganze komponierbare Funktion anwenden möchten, übergeben Sie einen Dp-Radius an Modifier.blur. Übergeben Sie einen einzelnen radius-Wert, um Inhalte sowohl horizontal (X) als auch vertikal (Y) gleichmäßig weichzuzeichnen:

@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)),
            ),
    )
}

Ein Hund, der sowohl auf der horizontalen als auch auf der vertikalen Achse gleichmäßig unscharf ist.
Abbildung 2: Ein Hund, der sowohl auf der horizontalen als auch auf der vertikalen Achse gleichmäßig unscharf ist.

Wenn Sie einen gerichteten Bewegungsunschärfeeffekt erstellen möchten, übergeben Sie separate radiusX- und radiusY-Werte an Modifier.blur. Sowohl radiusX als auch radiusY müssen größer als 0.dp sein, damit der Unschärfeeffekt angewendet wird, wie im folgenden Beispiel gezeigt:

@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)),
            ),
    )
}

Ein Hund mit einem starken horizontalen Bewegungsunschärfeeffekt.
Abbildung 3: Ein quadratisches Bild eines Hundes mit einem starken horizontalen Bewegungsunschärfeeffekt.

Progressive Unschärfe anwenden

Bei einer progressiven Unschärfe variiert der Unschärferadius innerhalb einer zusammensetzbaren Funktion, wodurch ein fließender Übergang zwischen scharfen und unscharfen Bereichen entsteht.

Übergeben Sie einen BlurRadiusSpec an Modifier.blur. Verwenden Sie beispielsweise BlurRadiusSpec.verticalGradient mit startRadius = 0.dp und endRadius = 6.dp, um den oberen Teil eines Bildes scharf zu halten, während er nach unten hin zunehmend unscharf wird, wie im folgenden Beispiel gezeigt:

@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)),
            ),
    )
}

Ein Hund, der oben scharf ist und nach unten hin immer unschärfer wird.
Abbildung 4: Ein Bild eines Hundes, das oben scharf ist und nach unten hin immer unschärfer wird.

Unschärfegradienten mit BlurRadiusSpec angeben

In BlurRadiusSpec werden Maße in Dp festgelegt und beim Zeichnen automatisch an die Größe und Anzeigedichte der Ebene angepasst. Räumlich variierende Unschärfen sind nach der Konvertierung auf 150 Pixel begrenzt, während es bei BlurRadiusSpec.uniform keine Begrenzung gibt.

In der folgenden Tabelle sind die für BlurRadiusSpec verfügbaren Factory-Funktionen aufgeführt:

BlurRadiusSpec-Factory Beschreibung
BlurRadiusSpec.verticalGradient Ändert den Unschärferadius vertikal von oben (0f) nach unten (1f) über die Ebene hinweg.
BlurRadiusSpec.horizontalGradient Ändert den Unschärferadius horizontal vom linken Rand (0f) zum rechten Rand (1f).
BlurRadiusSpec.linearGradient Wendet einen gerichteten Unschärfeübergang entlang einer geraden Linie an, die bestimmte DpOffset-Koordinaten verbindet.
BlurRadiusSpec.radialGradient Verteilt die Unschärfe von einem Fokuspunkt nach außen bis zur Grenze von fallOffRadius.
BlurRadiusSpec.uniform Wendet einen gleichmäßigen Unschärferadius auf die gesamte Ebene an.
BlurRadiusSpec.shader Verwendet den Alphakanal eines benutzerdefinierten Shader, um die maxRadius an jedem Pixel zu steuern und zu skalieren.

Weichzeichnungsverteilung mit BlurStop anpassen

Bei Standard-Verlaufsunschärfen wird linear zwischen 0f und 1f interpoliert. Wenn Sie die Verteilung der Unschärfe auf einer Oberfläche anpassen möchten, z. B. um mehrere Kanten unscharf zu machen oder einen mittleren Bereich vollständig scharf zu halten, übergeben Sie ein List<BlurStop> mit 2 bis 16 BlurStop-Einträgen an verticalGradient, horizontalGradient, linearGradient oder radialGradient. Definieren Sie für jeden BlurStop-Eintrag Folgendes:

  • fraction: Die relative Position entlang des Farbverlaufs von 0.0f bis 1.0f. Die Haltestellen werden automatisch nach Fraktion sortiert.
  • radius: Der Unschärferadius in Dp, der an dieser Bruchposition angewendet wird.

Beispiel: Vier Stopps machen die oberen und unteren Ränder eines Bildes unscharf, während die Mitte vollständig scharf bleibt, wie im folgenden Beispiel gezeigt:

@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,
            ),
    )
}

Ein Hund mit weichgezeichneten oberen und unteren Rändern, während der mittlere horizontale Streifen scharf fokussiert ist.
Abbildung 5. Ein Bild eines Hundes mit unscharfen oberen und unteren Rändern, während der mittlere horizontale Streifen scharf fokussiert ist.

Ebeneneigenschaften mit BlurScope konfigurieren

Anstatt blurRadiusSpec direkt zu übergeben, können Sie einen Konfigurationsblock an Modifier.blur { ... } übergeben. Dieser Block wird in BlurScope ausgeführt, sodass Sie direkten Zugriff auf die Layoutdichte und die folgenden Eigenschaften haben:

  • size: DpSize: Die gemessene Breite und Höhe der weichgezeichneten Ebene in Dp, die den Koordinatenraum für die Geometrie des Farbverlaufs definiert.
  • blurRadiusSpec: BlurRadiusSpec: Die Konfiguration des Unschärferadius auf der Oberfläche. Die Standardeinstellung ist BlurRadiusSpec.uniform(0.dp) (keine Unkenntlichmachung).
  • edgeTreatment: BlurredEdgeTreatment: Strategie zum Abtasten und Ausschneiden von Pixeln außerhalb der Inhaltsgrenzen. Die Standardeinstellung ist BlurredEdgeTreatment.Rectangle.
  • alpha: Float: Deckkraft der weichgezeichneten Ebene im Bereich 0f..1f. Die Standardeinstellung ist 1f.

Da der BlurScope-Block während der Grafiklayerphase nach der Messung und dem Layout ausgeführt wird, können Sie die Farbverlaufsgeometrie aus size berechnen, ohne eine Neuzusammensetzung auszulösen.

Kantenbeschneidung mit BlurredEdgeTreatment steuern

Da beim Weichzeichnen benachbarte Pixel innerhalb des Weichzeichnungsradius abgetastet werden, erstreckt sich die weichgezeichnete Ausgabe um den Weichzeichnungsradius über die ursprünglichen Inhaltsgrenzen hinaus. BlurredEdgeTreatment bestimmt, wie Pixel außerhalb der ursprünglichen Grenzen abgetastet werden und ob das Ergebnis auf eine Form zugeschnitten wird.

BlurredEdgeTreatment funktioniert sowohl mit gleichmäßiger als auch mit progressiver Unschärfe:

BlurredEdgeTreatment Verhalten Ausgabe
BlurredEdgeTreatment.Rectangle (Standard) Schneidet das Unkenntlichmachungsergebnis auf die rechteckigen Grenzen des Originalinhalts zu und tastet die nächstgelegenen Randpixel (TileMode.Clamp) ab. Ein unscharfes Bild eines Hundes, das auf einen scharfen rechteckigen Rahmen zugeschnitten ist.
BlurredEdgeTreatment(shape) Schneidet das Unschärfeergebnis auf die angegebene Shape (z. B. RoundedCornerShape(8.dp)) zu und nimmt die nächstgelegenen Randpixel (TileMode.Clamp) als Stichprobe. Das Unschärfeergebnis bleibt an der Formgrenze scharf, ohne über die ursprünglichen Grenzen hinauszugehen. Ein unscharfes Bild eines Hundes, das auf eine Form mit abgerundeten Ecken und scharfen Kanten zugeschnitten ist.
BlurredEdgeTreatment.Unbounded Das Ergebnis der Weichzeichnung wird nicht abgeschnitten (TileMode.Decal). Pixel außerhalb der Inhaltsgrenzen werden als transparentes Schwarz dargestellt, sodass die äußeren Ränder des Bildes über die ursprünglichen Grenzen hinaus unscharf und verschwommen erscheinen. Ein unscharfes Bild eines Hundes, dessen Ränder über die ursprünglichen Grenzen hinaus weich auslaufen.

Unter Häufige Anwendungsfälle für Unschärfe finden Sie Beispiele dafür, wie diese APIs in vollständigen UI-Mustern kombiniert werden, z. B. um die Ränder von scrollenden Inhalten auszublenden, einen Fokuspunkt hervorzuheben oder eine Unschärfe mit einem benutzerdefinierten Shader zu maskieren.