이번 포스팅은 간단하면서 궁금한 Icon 컴포저블과 Image 컴포저블의 차이점을 알아보겠다!
사실 둘 다 사진을 보여주는 컴포저블이라서 처음에는 어떤 경우에 Icon을 사용하고 어떤 경우에는 Image를 사용하는지 구분이 안 갔다.
그래서 이번에 공부하는 겸 작성해보기로 했다.
# Icon
@Composable
fun Icon(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
tint: Color = LocalContentColor.current.copy(alpha = LocalContentAlpha.current)
) {
...
...
}
위 코드는 Icon 컴포저블 내부이다. 각 인자 별로 알아보자!
위처럼 | |
// tint 사용 예시
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = "좋아요",
tint = Color.Red // 아이콘을 빨간색으로 변경
)
// 컨텍스트 색상 사용
Icon(
imageVector = Icons.Default.Favorite,
contentDescription = "좋아요",
tint = MaterialTheme.colors.primary // 테마의 기본 색상 사용
)
Icon은 tint 속성으로 해당 Icon의 색을 조절할 수 있다.
# Image
@Composable
fun Image(
painter: Painter,
contentDescription: String?,
modifier: Modifier = Modifier,
alignment: Alignment = Alignment.Center,
contentScale: ContentScale = ContentScale.Fit,
alpha: Float = DefaultAlpha,
colorFilter: ColorFilter? = null
) {
...
...
}
이제 Image 컴포저블 내부 속성을 알아보자!
Painter / ImageBitmap / ImageVector | 표시할 Painter / ImageBitmap / ImageVector 형식의 데이터 첫번째 인자로는 Painter / ImageBitmap / ImageVector 이 3개가 들어 갈 수 있다. |
contentDescription | 해당 이미지에 대한 설명 (접근성 목적) |
modifier | 이미지에 대한 수정자 (크기, 패딩 등 조정) |
alignment | 이미지가 지정된 경계 내에서 배치되는 위치를 결정한다. |
contentScale | 이미지의 크기가 지정된 경계와 다를 때 이미지를 어떻게 조정할지 결정한다. |
alpha | 이미지의 투명도를 설정한다. |
colorFilter | 이미지에 적용되는 색상필터 |
여기서 Icon 컴포저블에 없는 속성은 contentScale, alpha, colorFilter이다.
## contentScale
해당 속성은 이미지의 크기가 지정된 경계와 다를 때 이미지를 어떻게 조정할지 결정하는 속성이다.
ContentScale에는 여러가지 설정을 할 수 있다.
예시로 세로가 긴 이미지와 가로가 긴 이미지가 있다고 가정해 보자.
### ContentScale.Fit (Default)
- 가로세로 비율(기본값)을 유지하면서 이미지의 크기를 균일하게 조정한다.
- 콘텐츠가 크기보다 작으면 이미지는 경계에 맞게 확대 조정된다.
- 따로 contentScale을 설정하지 않으면 Fit으로 기본 적용이다.
- 이미지 전체를 왜곡 없이 보여주고 싶을 때, 이미지의 어떤 부분도 잘리지 않아야 할 때 사용 한다.
contentScale = ContentScale.Fit,
### ContentScale.Crop
- 사용 가능한 공간에 맞게 이미지를 가운데 중심으로 자른다.
- 여백 없이 컨테이너를 채우면서 이미지 왜곡을 피하고 싶을 때, 이미지의 중심 부분이 가장 중요할 때 사용 한다.
contentScale = ContentScale.Crop,
### ContentScale.FillHeight
- 경계가 대상 높이와 일치하도록 가로세로 비율을 유지하면서 소스의 크기를 조정한다.
쉽게 말하면 세로 크기 기준으로 소스의 크기 설정
- 세로 방향으로 컨테이너를 채우고 싶을 때, 수직 리스트나 갤러리에서 일관된 높이가 필요할 때 사용 한다.
contentScale = ContentScale.FillHeight,
### ContentScale.FillWidth
- 경계가 대상 너비와 일치하도록 가로세로 비율을 유지하면서 소스의 크기를 조정한다.
쉽게 말하면 가로 크기 기준으로 소스의 크기 설정
- 가로 방향으로 컨테이너를 채우고 싶을 때, 수평 리스트나 갤러리에서 일관된 너비가 필요할 때 사용 한다.
contentScale = ContentScale.FillWidth,
### ContentScale.FillBounds
- 대상 경계를 채우도록 콘텐츠의 크기를 균일하지 않게 세로 및 가로로 조정한다.
- 이미지의 가로세로 비율(aspect ratio)을 무시하고 지정된 너비와 높이에 맞게 이미지를 늘리거나 줄이기 때문에 이미지가 왜곡될 수 있다.
- 이미지의 원래 비율을 유지할 필요가 없을 때, 배경 이미지나 패턴으로 사용할 때 사용 한다.
contentScale = ContentScale.FillBounds,
### ContentScale.Inside
- 대상 경계 내에서 가로세로 비율을 유지하도록 소스의 크기를 조정한다.
- 소스가 두 측정기준에서 모두 대상보다 작거나 같으면 `None`과 유사하게 동작한다.
- 작은 이미지를 원래 크기로 유지하고 싶을 때, 이미지 확대로 인한 화질 저하를 방지하고 싶을 때 사용 한다.
contentScale = ContentScale.Inside,
### ContentScale.None
- 소스에 크기 조정을 적용하지 않는다.
- 컨테이너보다 이미지가 크면 잘릴 수 있고, 작으면 여백이 생긴다.
- 프로그래밍 방식으로 크기를 제어할 때, 특정 크기의 아이콘이나 에셋을 표시할 때 사용 한다.
contentScale = ContentScale.None,
## alpha
- 이미지의 투명도를 설정한다.
- 기본값은 1.0F
- 자료형: Float / 0.0f ~ 1.0f 범위이다. (ex 50% 투명하게 하고 싶으면 0.5f)
- 이미지를 반투명하게 표시하고 싶을 때, 배경 이미지의 명암을 낮춰 전경 콘텐츠를 강조하고 싶을 때 사용 한다.
alpha = 1f // 100% 설정
alpha = 0.5f // 50% 설정
## colorFilter
- 이미지의 색상을 변형하거나 조정한다.
- 기본값은 null
- 자료형: ColorFilter
- 이미지의 색상을 변경하고 싶을 때, 이미지에 색조를 적용할 때 사용 한다.
Icon의 tint 내부도 colorFilter를 사용해서 구현했다.
// Icon Tint 내부 구현 val colorFilter = if (tint == Color.Unspecified) null else ColorFilter.tint(tint)
### ColorFilter 유형
tint - 이미지에 단일 색상 필터를 적용한다.
// 이미지에 빨간색 필터 적용
ColorFilter.tint(Color.Red)

lighting - 곱셈 색상과 덧셈 색상을 사용해 이미지를 변형한다.
- 이미지의 색상 톤을 조정하거나 특수 효과를 만들 때 더 유용하다.
ColorFilter.lighting(Color.Gray, Color.Red) // 회색 곱셈 효과 + 빨간색 덧셈 효과
colorMatrix - ColorMatrix를 사용해 더 복잡한 색상 변형을 적용한다.
// 흑백 효과 적용
val matrix = ColorMatrix().apply { setToSaturation(0f) }
ColorFilter.colorMatrix(matrix)

# Icon Vs Image
이제 각 컴포저블을 알아봤으니 서로 정말 비슷하다는 것을 알았을 것이다.
아래 표를 통해 차이점을 정리해보았다.
특성 | Icon | Image |
용도 | 단색 UI 아이콘 | 다양한 형태의 이미지 (사진, 복잡한 그래픽) |
색상 변경 | tint 속성 (간편하다) | colorFilter 속성 (다양한 효과) |
기본 색상 | 테마 색상 자동 적용 | 원본 색상 유지 |
크기 조정 | Material Design 가이드라인에 맞게 최적화 | contentScale 속성으로 세밀한 제어 가능 |
적합한 사용 사례 | UI 아이콘, 버튼 아이콘, 심볼 | 사진, 일러스트, 배경 이미지, 복잡한 그래픽 |
따라서 Icon 사용 시기는 UI 요소로서의 단색 아이콘이 필요할 때, Material Design을 따를 때 이고 Image 사용 시기는 복잡한 이미지나 사진을 표시할 때, 다양한 스케일링이나 색상 효과가 필요할 때라고 볼 수 있다.
# 느낀 점
평소 개발 할 때 본능적으로 단색 아이콘 표시 할 때 Icon으로 사용하고 Image와 정확한 차이점을 몰랐었는데 이번 기회에 차이점을 알게 되어서 좋았다.
그리고 생각 보다 Image 컴포저블에서 이미지에 대해 많은 처리를 할 수 있다는 것도 알았다.
참고
https://developer.android.com/develop/ui/compose/graphics/images/customize?hl=ko