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

Изображения можно настроить с помощью свойств компонуемого Image ( contentScale , colorFilter ). Вы также можете применить существующие Modifiers , чтобы применить к вашему Image различные эффекты. Модификаторы можно использовать для любого Composable , а не только для Composable Image , тогда как contentScale и colorFilter являются явными параметрами для Composable 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.Подогнать портретContentScale.Подогнать ландшафт
ContentScale.Crop : обрезает изображение по центру в доступное пространство. ContentScale.Обрезать портретContentScale.Обрезка ландшафта
ContentScale.FillHeight : Масштабируйте источник, сохраняя соотношение сторон, чтобы границы соответствовали высоте назначения. Портрет ContentScale.FillHeightContentScale.FillHeight ландшафт
ContentScale.FillWidth : Масштабируйте источник, сохраняя соотношение сторон, чтобы границы соответствовали ширине назначения. Портрет ContentScale.FillWidthContentScale.FillWidth ландшафт
ContentScale.FillBounds : неравномерно масштабируйте содержимое по вертикали и горизонтали, чтобы заполнить границы назначения. (Примечание. Это приведет к искажению изображений, если вы поместите их в контейнеры, соотношение сторон которых не соответствует точному изображению.) Портрет ContentScale.FillBoundsContentScale.FillBounds ландшафт
ContentScale.Inside : Масштабируйте источник, чтобы сохранить соотношение сторон внутри границ назначения. Если источник меньше или равен месту назначения в обоих измерениях, он ведет себя аналогично «Нет». Содержимое всегда будет находиться в пределах границ. Если содержимое меньше границ, масштабирование не применяется. Исходное изображение больше границ: ContentScale.Inside портрет, исходное изображение превышает границы Исходное изображение меньше границ: ContentScale.Inside портрет, исходное изображение меньше границ Исходное изображение больше границ: ContentScale.Внутри ландшафта, исходное изображение превышает границы. Исходное изображение меньше границ: ContentScale.Внутри ландшафта, исходное изображение меньше границ
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. Вырежьте изображение и создайте рамку вокруг него.

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

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)
)

Color.Green оттенок с BlendMode.Darken
Рис. 8. Оттенок Color.Green с 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))
        )
)

Эффект BlurEffect применен к изображению
Рис. 12. Эффект BlurEffect, примененный к изображению.

При размытии 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.Неограниченный
Рисунок 13. BlurEdgeTreatment.Unbounded.
{% дословно %} {% дословно %} {% дословно %} {% дословно %}