Настройка изображения

Изображения можно настраивать с помощью свойств в компонуемом Image ( contentScale , colorFilter ). Вы также можете применять существующие Modifiers для применения различных эффектов к вашему Image . Модификаторы можно использовать в любом компонуемом изображении , а не только в компонуемом Image , тогда как contentScale и colorFilter являются явными параметрами компонуемого Image .

Масштаб содержания

Укажите параметр contentScale , чтобы обрезать или изменить масштаб изображения внутри его границ. По умолчанию, если параметр contentScale не указан, будет использоваться ContentScale.Fit .

В приведенном ниже примере размер компонуемого изображения ограничен 150 dp с рамкой, а фон для компонуемого Image установлен на желтый цвет, чтобы продемонстрировать различные параметры ContentScale в таблице ниже.

val imageModifier = Modifier
    .size(150.dp)
    .border(BorderStroke(1.dp, Color.Black))
    .background(Color.Yellow)
Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Fit,
    modifier = imageModifier
)

Установка различных опций ContentScale приведет к различным результатам. Ниже приведена таблица, которая может помочь в выборе нужного вам режима ContentScale :

Исходное изображение Исходное изображение портретаИсходное изображение ландшафта
ContentScale Результат - Портретное изображение: Результат - Пейзажное изображение:
ContentScale.Fit : Масштабировать изображение равномерно, сохраняя соотношение сторон (по умолчанию). Если содержимое меньше размера, изображение масштабируется, чтобы соответствовать границам. ContentScale.Fit портретContentScale.Fit ландшафт
ContentScale.Crop : кадрирование изображения по центру доступного пространства. ContentScale.Обрезка портретаContentScale.Crop ландшафт
ContentScale.FillHeight : Масштабировать источник, сохраняя соотношение сторон так, чтобы границы соответствовали высоте назначения. ContentScale.FillHeight портретContentScale.FillHeight альбомная ориентация
ContentScale.FillWidth : масштабирует источник, сохраняя соотношение сторон так, чтобы границы соответствовали ширине назначения. ContentScale.FillWidth портретContentScale.FillWidth альбомная ориентация
ContentScale.FillBounds : масштабирует содержимое по вертикали и горизонтали неравномерно, чтобы заполнить границы назначения. (Примечание: это приведет к искажению изображений, если вы поместите их в контейнеры, которые не соответствуют точному соотношению сторон изображения) Портрет ContentScale.FillBoundsContentScale.FillBounds ландшафт
ContentScale.Inside : Масштабировать источник, чтобы сохранить соотношение сторон внутри границ назначения. Если источник меньше или равен назначению в обоих измерениях, он ведет себя аналогично `None`. Содержимое всегда будет находиться в пределах границ. Если содержимое меньше границ, масштабирование не применяется. Исходное изображение больше границ: ContentScale.Inside портрет, исходное изображение больше границ Исходное изображение меньше границ: ContentScale.Inside портрет, исходное изображение меньше границ Исходное изображение больше границ: ContentScale.Inside ландшафт, исходное изображение больше границ Исходное изображение меньше границ: ContentScale.Inside ландшафт, исходное изображение меньше границ
ContentScale.None : Не применять масштабирование к источнику. Если содержимое меньше границ назначения, оно не будет масштабироваться для соответствия области. Исходное изображение больше границ: ContentScale.None портрет, исходное изображение больше границ Исходное изображение меньше границ: ContentScale.None портрет, исходное изображение меньше границ Исходное изображение больше границ: ContentScale.None альбомная ориентация, исходное изображение больше границ Исходное изображение меньше границ: ContentScale.None альбомная ориентация, исходное изображение меньше границ

Вырезать Image , которое можно скомпоновать в форму

Чтобы вписать изображение в форму, используйте встроенный модификатор clip . Чтобы обрезать изображение до круглой формы, используйте Modifier.clip(CircleShape) :

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .size(200.dp)
        .clip(CircleShape)
)

Обрезка изображения с помощью CircleShape
Рисунок 1 : Обрезка изображения с помощью CircleShape

Форма скругленных углов — используйте Modifier.clip(RoundedCornerShape(16.dp) ) с размером углов, которые вы хотите скруглить:

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .size(200.dp)
        .clip(RoundedCornerShape(16.dp))
)

Обрезка изображения с помощью RoundedCornerShape
Рисунок 2 : Обрезка изображения с помощью RoundedCornerShape

Вы также можете создать собственную форму обрезки, расширив Shape и указав Path , вокруг которой будет выполняться обрезка:

class SquashedOval : Shape {
    override fun createOutline(
        size: Size,
        layoutDirection: LayoutDirection,
        density: Density
    ): Outline {
        val path = Path().apply {
            // We create an Oval that starts at ¼ of the width, and ends at ¾ of the width of the container.
            addOval(
                Rect(
                    left = size.width / 4f,
                    top = 0f,
                    right = size.width * 3 / 4f,
                    bottom = size.height
                )
            )
        }
        return Outline.Generic(path = path)
    }
}

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .size(200.dp)
        .clip(SquashedOval())
)

Обрезка изображения с помощью пользовательской формы пути
Рисунок 3 : Обрезка изображения с помощью пользовательской формы пути

Добавить границу к компонуемому Image

Распространенной операцией является объединение Modifier.border() с Modifier.clip() для создания рамки вокруг изображения:

val borderWidth = 4.dp
Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .size(150.dp)
        .border(
            BorderStroke(borderWidth, Color.Yellow),
            CircleShape
        )
        .padding(borderWidth)
        .clip(CircleShape)
)

Вырежьте изображение и добавьте вокруг него рамку.
Рисунок 4 : Вырежьте изображение и добавьте вокруг него рамку.

Если вы хотите создать градиентную рамку, вы можете использовать API Brush , чтобы нарисовать радужную градиентную рамку вокруг изображения:

val rainbowColorsBrush = remember {
    Brush.sweepGradient(
        listOf(
            Color(0xFF9575CD),
            Color(0xFFBA68C8),
            Color(0xFFE57373),
            Color(0xFFFFB74D),
            Color(0xFFFFF176),
            Color(0xFFAED581),
            Color(0xFF4DD0E1),
            Color(0xFF9575CD)
        )
    )
}
val borderWidth = 4.dp
Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier
        .size(150.dp)
        .border(
            BorderStroke(borderWidth, rainbowColorsBrush),
            CircleShape
        )
        .padding(borderWidth)
        .clip(CircleShape)
)

Граница круга с радужным градиентом
Рисунок 5 : Граница круга с радужным градиентом

Установите пользовательское соотношение сторон

Чтобы преобразовать изображение в изображение с пользовательским соотношением сторон, используйте Modifier.aspectRatio(16f/9f) чтобы задать пользовательское соотношение сторон для изображения (или любого другого компонуемого изображения).

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    modifier = Modifier.aspectRatio(16f / 9f)
)

Использование Modifier.aspectRatio(16f/9f) для изображения
Рисунок 6 : Использование Modifier.aspectRatio(16f/9f) для изображения

Цветовой фильтр — преобразует цвета пикселей изображения.

Компонуемое изображение имеет параметр colorFilter , который может изменять вывод отдельных пикселей вашего изображения.

Тонирование изображения

Использование ColorFilter.tint(color, blendMode) применит режим смешивания с заданным цветом к вашему компонуемому Image . ColorFilter.tint(color, blendMode) использует BlendMode.SrcIn для тонирования содержимого, что означает, что предоставленный цвет будет показан там, где изображение отображается на экране. Это полезно для иконок и векторов, которые должны быть тематически оформлены по-разному.

Image(
    painter = painterResource(id = R.drawable.baseline_directions_bus_24),
    contentDescription = stringResource(id = R.string.bus_content_description),
    colorFilter = ColorFilter.tint(Color.Yellow)
)

ColorFilter.tint применен с BlendMode.SrcIn
Рисунок 7 : ColorFilter.tint, примененный с BlendMode.SrcIn

Другие BlendMode приводят к разным эффектам. Например, установка BlendMode.Darken с Color.Green на изображении дает следующий результат:

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    colorFilter = ColorFilter.tint(Color.Green, blendMode = BlendMode.Darken)
)

Цвет.Зеленый оттенок с BlendMode.Darken
Рисунок 8 : Цвет. Зеленый оттенок с BlendMode. Darken

Дополнительную информацию о различных доступных режимах наложения см. в справочной документации BlendMode.

Применение фильтра Image с цветовой матрицей

Трансформируйте изображение с помощью параметра цветовой матрицы ColorFilter . Например, чтобы применить черно-белый фильтр к изображениям, можно использовать ColorMatrix и установить насыщенность на 0f .

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) })
)

Цветовая матрица с насыщенностью 0 (черно-белое изображение)
Рисунок 9 : Цветовая матрица с насыщенностью 0 (черно-белое изображение)

Отрегулируйте контрастность или яркость компонуемого Image

Чтобы изменить контрастность и яркость изображения, вы можете использовать ColorMatrix для изменения значений:

val contrast = 2f // 0f..10f (1 should be default)
val brightness = -180f // -255f..255f (0 should be default)
val colorMatrix = floatArrayOf(
    contrast, 0f, 0f, 0f, brightness,
    0f, contrast, 0f, 0f, brightness,
    0f, 0f, contrast, 0f, brightness,
    0f, 0f, 0f, 1f, 0f
)
Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    colorFilter = ColorFilter.colorMatrix(ColorMatrix(colorMatrix))
)

Отрегулированная яркость и контрастность изображения с помощью ColorMatrix
Рисунок 10 : Яркость и контрастность изображения, настроенные с помощью ColorMatrix

Инвертировать цвета компонуемого Image

Чтобы инвертировать цвета изображения, установите ColorMatrix для инвертирования цветов:

val colorMatrix = floatArrayOf(
    -1f, 0f, 0f, 0f, 255f,
    0f, -1f, 0f, 0f, 255f,
    0f, 0f, -1f, 0f, 255f,
    0f, 0f, 0f, 1f, 0f
)
Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    colorFilter = ColorFilter.colorMatrix(ColorMatrix(colorMatrix))
)

Инвертированные цвета на изображении
Рисунок 11 : Инвертированные цвета на изображении

Размытие Image , компонуемого

Чтобы размыть изображение, используйте Modifier.blur() , указав радиусы radiusX и radiusY , которые задают радиус размытия в горизонтальном и вертикальном направлении соответственно.

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 = 10.dp,
            edgeTreatment = BlurredEdgeTreatment(RoundedCornerShape(8.dp))
        )
)

К изображению применен эффект размытия
Рисунок 12 : Эффект размытия, примененный к изображению

При размытии Images рекомендуется использовать BlurredEdgeTreatment(Shape) вместо BlurredEdgeTreatment.Unbounded , поскольку последний используется для размытия произвольных рендеров, которые, как ожидается, будут отображаться за пределами границ исходного содержимого. Для изображений, скорее всего, они не будут отображаться за пределами границ содержимого; тогда как размытие скругленного прямоугольника может потребовать этого различия.

Например, если мы установим для BlurredEdgeTreatment значение Unbounded на изображении выше, края изображения будут выглядеть размытыми, а не резкими:

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 = 10.dp,
            edgeTreatment = BlurredEdgeTreatment.Unbounded
        )
        .clip(RoundedCornerShape(8.dp))
)

BlurEdgeTreatment.Unbounded
Рисунок 13 : BlurEdgeTreatment.Unbounded
{% дословно %} {% endverbatim %} {% дословно %} {% endverbatim %}