Compose에서 흐리게 처리

블러 효과는 시각적 세부정보를 부드럽게 하고, 사진의 피사계 심도를 만들고, 전경 UI 요소에 초점을 맞춥니다. Jetpack Compose에서 Modifier.blur를 사용하여 이미지, 도형, 텍스트, 레이아웃 컨테이너를 비롯한 컴포저블 내에 그려진 콘텐츠를 흐리게 처리합니다. Modifier.blur를 적용하면 컴포저블이 별도의 그래픽 레이어로 렌더링됩니다.

왼쪽: 원본 이미지 가운데: 전체 표면에 균일한 블러가 적용된 이미지 오른쪽: 상단은 선명하고 하단으로 갈수록 흐려지는 점진적 블러가 적용된 이미지
그림 1. 왼쪽: 원본 이미지 가운데: 전체 표면에 균일한 블러가 적용된 이미지 오른쪽: 상단은 선명하고 하단으로 갈수록 흐려지는 점진적 흐림 효과가 적용된 이미지

디자인 목표에 따라 두 가지 방법으로 블러를 변경할 수 있습니다.

  • 균일한 블러: 전체 컴포저블에 일정한 블러 반경을 적용합니다. 두 축에 동일하게 적용하거나 가로 및 세로 반경을 독립적으로 적용할 수 있습니다 (radiusX, radiusY).
  • 점진적 블러: BlurRadiusSpec 그라데이션 또는 맞춤 Shader를 사용하여 컴포저블 전체에서 블러 반경을 공간적으로 변경합니다.

균일한 흐리게 처리 적용

전체 컴포저블에 일정한 블러를 적용하려면 Dp 반경을 Modifier.blur에 전달합니다. 단일 radius 값을 전달하여 가로 (X) 및 세로 (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)),
            ),
    )
}

가로축과 세로축 모두에서 균일하게 흐리게 처리된 개
그림 2. 가로축과 세로축 모두에서 균일하게 흐리게 처리된 개

방향성 모션 블러 효과를 만들려면 별도의 radiusX 및 radiusY 값을 Modifier.blur에 전달합니다. 다음 예와 같이 흐리게 처리 효과를 적용하려면 radiusX 및 radiusY가 모두 0.dp보다 커야 합니다.

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

강한 수평 모션 블러 효과가 적용된 개
그림 3. 가로 방향의 강한 모션 블러 효과가 적용된 강아지의 정사각형 이미지

점진적 블러 적용

점진적 블러는 컴포저블 전체에서 블러 반경을 변경하여 선명한 영역과 흐린 영역 간에 부드러운 전환을 만듭니다.

BlurRadiusSpec를 Modifier.blur에 전달합니다. 예를 들어 다음 예와 같이 BlurRadiusSpec.verticalGradient를 startRadius = 0.dp 및 endRadius = 6.dp와 함께 사용하여 이미지 상단을 선명하게 유지하면서 하단으로 갈수록 점진적으로 흐리게 처리합니다.

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

위쪽은 선명하고 아래쪽으로 갈수록 점차 흐려지는 개
그림 4. 상단은 선명하고 하단으로 갈수록 점차 흐려지는 강아지 이미지

BlurRadiusSpec로 블러 그라데이션 지정

BlurRadiusSpec에서 측정값은 Dp로 설정되며 그려질 때 레이어의 크기와 디스플레이 밀도에 맞게 자동으로 조정됩니다. 공간적으로 변화하는 블러는 변환 후 150픽셀로 제한되지만 BlurRadiusSpec.uniform에는 제한이 없습니다.

다음 표에는 BlurRadiusSpec에서 사용할 수 있는 팩토리 함수가 나와 있습니다.

BlurRadiusSpec 공장 설명
BlurRadiusSpec.verticalGradient 레이어 전체에서 흐리게 처리 반경을 위 (0f)에서 아래 (1f)로 세로로 부드럽게 변경합니다.
BlurRadiusSpec.horizontalGradient 왼쪽 가장자리 (0f)에서 오른쪽 가장자리 (1f)까지 가로로 흐리게 처리 반경을 부드럽게 변경합니다.
BlurRadiusSpec.linearGradient 특정 DpOffset 좌표를 연결하는 직선을 따라 방향성 블러 전환을 적용합니다.
BlurRadiusSpec.radialGradient 초점에서 fallOffRadius 경계를 향해 바깥쪽으로 흐림 효과를 적용합니다.
BlurRadiusSpec.uniform 전체 레이어에 균일한 블러 반경을 적용합니다.
BlurRadiusSpec.shader 맞춤 Shader의 알파 채널을 사용하여 각 픽셀에서 maxRadius를 제어하고 조정합니다.

BlurStop로 흐림 효과 분포 맞춤설정

표준 그라데이션 블러는 0f와 1f 사이를 선형으로 보간합니다. 여러 가장자리를 흐리게 처리하거나 중간 섹션을 완전히 선명하게 유지하는 등 표면 전체의 흐림 분포를 맞춤설정하려면 2~16개의 BlurStop 항목이 포함된 List<BlurStop>를 verticalGradient, horizontalGradient, linearGradient 또는 radialGradient에 전달합니다. 각 BlurStop 항목에 대해 다음을 정의합니다.

  • fraction: 0.0f에서 1.0f까지 그라데이션을 따라 상대적인 위치입니다. 중지점은 분수에 따라 자동으로 정렬됩니다.
  • radius: 해당 비율 위치에 적용된 Dp의 블러 반경입니다.

예를 들어 다음 예와 같이 4개의 중지점은 이미지의 상단과 하단 가장자리를 흐리게 처리하면서 중간은 완전히 선명하게 유지합니다.

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

가운데 가로 영역은 선명하게 초점을 맞추고 상단과 하단 가장자리는 흐리게 처리한 강아지
그림 5. 가운데 가로 영역은 선명하게 초점이 맞고 상단과 하단 가장자리는 흐리게 처리된 강아지 이미지

BlurScope로 레이어 속성 구성

blurRadiusSpec를 직접 전달하는 대신 구성 블록을 Modifier.blur { ... }에 전달할 수 있습니다. 이 블록은 BlurScope 내에서 실행되므로 레이아웃 밀도와 다음 속성에 직접 액세스할 수 있습니다.

  • size: DpSize: Dp에서 흐리게 처리된 레이어의 측정된 너비와 높이로, 그라데이션 도형의 좌표 공간을 정의합니다.
  • blurRadiusSpec: BlurRadiusSpec: 표면의 흐림 반경 구성입니다. 기본값은 BlurRadiusSpec.uniform(0.dp) (흐리게 처리 없음)입니다.
  • edgeTreatment: BlurredEdgeTreatment: 콘텐츠 경계 외부의 픽셀을 샘플링하고 클리핑하는 데 사용되는 전략입니다. 기본값은 BlurredEdgeTreatment.Rectangle입니다.
  • alpha: Float: 0f..1f 범위에서 흐리게 처리된 레이어의 불투명도입니다. 기본값은 1f입니다.

BlurScope 블록은 측정 및 레이아웃 후 그래픽 레이어 단계에서 실행되므로 재구성을 트리거하지 않고도 size에서 그라데이션 도형을 계산할 수 있습니다.

thought BlurredEdgeTreatment로 가장자리 클리핑 제어

블러 처리는 블러 반경 내의 인접 픽셀을 샘플링하므로 블러 처리된 출력은 블러 반경만큼 원래 콘텐츠 경계를 넘어 확장됩니다. BlurredEdgeTreatment는 원래 경계 외부의 픽셀이 샘플링되는 방식과 결과가 도형에 맞게 잘리는지 여부를 결정합니다.

BlurredEdgeTreatment는 균일한 블러와 점진적인 블러 모두에서 작동합니다.

BlurredEdgeTreatment 동작 출력
BlurredEdgeTreatment.Rectangle(기본) 블러 결과를 원래 콘텐츠의 직사각형 경계로 자르고 가장 가까운 가장자리 픽셀을 샘플링합니다 (TileMode.Clamp). 선명한 직사각형 경계로 잘린 흐릿한 강아지 이미지
BlurredEdgeTreatment(shape) 블러 결과를 지정된 Shape (예: RoundedCornerShape(8.dp))로 자르고 가장 가까운 가장자리 픽셀 (TileMode.Clamp)을 샘플링합니다. 블러 처리된 결과가 원래 경계 외부로 번지지 않고 도형 경계에서 선명하게 유지됩니다. 가장자리가 날카롭고 모서리가 둥근 모양으로 잘린 흐릿한 개 이미지
BlurredEdgeTreatment.Unbounded 블러 결과 (TileMode.Decal)를 자르지 않습니다. 콘텐츠 경계 외부의 픽셀은 투명한 검은색을 샘플링하여 이미지의 바깥쪽 가장자리가 원래 경계를 넘어 흐릿하고 블러 처리된 것처럼 보이게 합니다. 가장자리가 원래 경계를 넘어 부드럽게 흐려지는 흐릿한 개 이미지

스크롤 콘텐츠의 가장자리 페이드, 초점 스포트라이트, 맞춤 셰이더를 사용한 블러 마스킹과 같은 전체 UI 패턴에서 이러한 API가 어떻게 결합되는지 알아보려면 일반적인 블러 사용 사례를 참고하세요.