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

Изображения можно настраивать с помощью свойств компонуемого объекта 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.Crop портретContentScale.Crop ландшафт
ContentScale.FillHeight : Масштабирует исходный объект, сохраняя соотношение сторон так, чтобы границы соответствовали высоте назначения. ContentScale.FillHeight портретContentScale.FillHeight альбомная ориентация
ContentScale.FillWidth : Масштабирует исходный объект, сохраняя соотношение сторон так, чтобы границы соответствовали ширине конечного объекта. ContentScale.FillWidth портретContentScale.FillWidth альбомная ориентация
ContentScale.FillBounds : неравномерно масштабирует содержимое по вертикали и горизонтали, чтобы заполнить границы области назначения. (Примечание: изображения будут искажены, если их поместить в контейнеры, не соответствующие точным пропорциям изображения.) Портрет ContentScale.FillBoundsContentScale.FillBounds ландшафт
ContentScale.Inside : Масштабирует исходный объект, сохраняя соотношение сторон в пределах конечного объекта. Если исходный объект меньше или равен конечному объекту по обоим измерениям, поведение аналогично `None`. Содержимое всегда будет находиться в пределах границ. Если содержимое меньше границ, масштабирование не применяется. Исходное изображение больше границ: ContentScale.Inside portrait, исходное изображение больше границ Исходное изображение меньше границ: ContentScale.Inside portrait, исходное изображение меньше границ Исходное изображение больше границ: 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 с цветовой матрицей

Преобразуйте изображение с помощью параметра ColorMatrix 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 %}