Удалить высоту по умолчанию с изображения в Jetpack Compose

Я хотел бы знать, есть ли какой-либо способ указать плагину Jetpack Compose, чтобы удалить высоту по умолчанию из компонента изображения, или единственный способ - перестроить ресурс изображения.

У меня есть это:

Image(
                    painter = painterResource(id = if (sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
                    contentDescription = "login_logo",
                    modifier = Modifier
                        .align(CenterHorizontally)
                        .fillMaxWidth()


Которые показывают, как это

Поскольку вы можете проверить, что изображение имеет высоту, которую я не добавляю к компоненту, поэтому должен ли я воссоздать актив или есть какой-то способ его удалить.

Заранее спасибо !

[РЕДАКТИРОВАТЬ]

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

 val offset = with(LocalDensity.current){
        4.dp.toPx()
    }


    val customCircleShape = GenericShape{ size: Size, layoutDirection: LayoutDirection ->
        addOval(
            Rect(
                offset = Offset(
                    offset, offset
                ),
                size = Size(
                    width = size.width - 2 * offset,
                    height = size.height - 2 * offset
                )
            )
        )
    }
Column(
                verticalArrangement = Arrangement.Top,
                modifier = Modifier
                    .clip(customCircleShape)
                    .shadow(4.dp, CircleShape)
                    .size(60.dp)
                    .background(Color.White)
            ) {
                Image(
                    painter = painterResource(id = if (sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
                    contentDescription = "login_logo",
                    modifier = Modifier
                        .align(Alignment.CenterHorizontally)
                        .fillMaxWidth()
                        .fillMaxHeight(0.25f)
                        .border(BorderStroke(2.dp, Color.White), CircleShape)
                        .background(Color.White)
                )
            }

Но граница все еще отображается как первая картинка, которую я добавил.

Что мне здесь не хватает?

[РЕДАКТИРОВАТЬ]

Неважно, насколько большой круг, который должен скрывать тень, не делайте этого.

Я добавляю изображение, которое я использую в качестве ссылки.

[РЕШЕНИЕ]

Я делаю работы, делая это:

val offset = with(LocalDensity.current){
        8.dp.toPx()
    }

    val customCircleShape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
        addOval(
            Rect(
                offset = Offset(
                    offset, offset
                ),
                size = Size(
                    width = size.width - 2 * offset,
                    height = size.height - 2 * offset
                )
            )
        )
    }

Image(
                    painter = painterResource(id = if (sessionToken.isNotEmpty()) R.drawable.ic_disa_logo else R.drawable.ic_cepsa_logo),
                    contentDescription = "login_logo",
                    contentScale = ContentScale.FillBounds,
                    modifier = Modifier
                        .align(CenterHorizontally)
                        .padding(10.dp)
                        .background(Color.White)
                        .clip(customCircleShape)
                        .size(80.dp),

                )

1
0
62
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Рассматривали ли вы попытку создать собственный эффект тени?

modifier = Modifier
                .size(100.dp)
                .clip(CircleShape)
                .shadow(elevation = 0.dp, shape = CircleShape)

Спасибо за ваши комментарии, и да, я уже пытался сделать это: .border(BorderStroke(2.dp, Color.White), CircleShape) .background(Color.White) и ваш код тоже, и не работает

Manuel Lucas 07.08.2023 12:59
Ответ принят как подходящий

Поскольку ваш логотип может содержаться внутри круга, вы можете сделать это несколькими способами.

1- Использование функций Path и clipPath внутри drawScope Modifier.drawWithContent.

2- Создание пользовательской формы круга меньшего размера, как в варианте 1, и применение Modifier.clip(customShape)

3- Использование BlendMode с назначением drawCircle внутри Modifier.drawWithContent.

Так как у меня нет твоего логотипа. Я создал изображение, которое рисует красный круг с некоторой тенью.

@Preview
@Composable
private fun MyImage() {
    Canvas(
        modifier = Modifier
            .shadow(4.dp, CircleShape)
            .size(60.dp)
            .background(Color.White)
    ) {

        drawCircle(color = Color.Red, radius = size.width / 2 - 5.dp.toPx())
    }
}

И реализовал этот модификатор как

@Preview
@Composable
fun Test() {
    Column(modifier = Modifier.fillMaxSize()) {

        Text(text = "Original")
        MyImage()

        Spacer(modifier = Modifier.height(10.dp))

        val path = remember {
            androidx.compose.ui.graphics.Path()
        }

        val offset = with(LocalDensity.current){
            4.dp.toPx()
        }


        val customCircleShape = GenericShape{size: Size, layoutDirection: LayoutDirection ->
            addOval(
                Rect(
                    offset = Offset(
                        offset, offset
                    ),
                    size = Size(
                        width = size.width - 2 * offset,
                        height = size.height - 2 * offset
                    )
                )
            )
        }

        Spacer(modifier = Modifier.height(10.dp))

        Text(text = "Clip with Shape")
        Box(modifier = Modifier.clip(customCircleShape)){
            MyImage()
        }
        Spacer(modifier = Modifier.height(10.dp))

        Text(text = "drawWithContent and clipPath")

        Box(
            modifier = Modifier.drawWithContent {


                if (path.isEmpty) {
                    path.addOval(
                        oval = Rect(
                            offset = Offset(
                                offset, offset
                            ),
                            size = Size(
                                width = size.width - 2 * offset,
                                height = size.height - 2 * offset
                            )
                        )
                    )
                }

                clipPath(path = path, clipOp = ClipOp.Intersect) {
                    [email protected]()

                }
            }
        ) {
            MyImage()
        }
    }
}

Результат

Хитрость заключается в том, чтобы создать Rect для овала, который имеет смещения в обоих направлениях.

Для образца BlendMode вы можете проверить ссылку ниже. Я вырезал изображение и Button придал ему форму прямоугольника.

Как подстричь или вырезать составной?

Редактировать

С изображением это как

Используется только клип с параметром пользовательской формы, но другие параметры могут быть применены либо к клипу, либо к добавлению собственной тени, как это сделал я.

@Preview
@Composable
private fun Test() {


    val offset = with(LocalDensity.current) {
        8.dp.toPx()
    }


    val customCircleShape = GenericShape { size: Size, layoutDirection: LayoutDirection ->
        addOval(
            Rect(
                offset = Offset(
                    offset, offset
                ),
                size = Size(
                    width = size.width - 2 * offset,
                    height = size.height - 2 * offset
                )
            )
        )
    }

    Column(
        Modifier
            .fillMaxSize()
            .padding(20.dp)
    ) {

        Text("ORIGINAL")

        Image(
            painter = painterResource(id = R.drawable.shell),
            contentDescription = null,
            contentScale = ContentScale.FillBounds,
        )

        Text("Clipped with Shape")

        Image(
            modifier = Modifier
                .border(1.dp, Color.Green)
                .clip(customCircleShape),
            painter = painterResource(id = R.drawable.shell),
            contentDescription = null,
            contentScale = ContentScale.FillBounds
        )


        Text("With Size and attached Modifier.shadow after")

        Image(
            modifier = Modifier
                .border(1.dp, Color.Green)
                .padding(10.dp)
                .shadow(6.dp, spotColor = Color.Cyan, shape = CircleShape)
                .background(Color.White)
                .clip(customCircleShape)
                .size(80.dp),
            painter = painterResource(id = R.drawable.shell),
            contentDescription = null,
            contentScale = ContentScale.FillBounds
        )
    }
}

Спасибо за полный ответ. Я попытаюсь угадать ваше предположение, но все еще показываю границу вокруг изображения. Я редактирую свой исходный вопрос, добавляя код

Manuel Lucas 07.08.2023 16:49

Значение, которое я использовал, является фиксированным значением, которое соответствует тени, которую я добавил в качестве образца. Пробовали увеличить? Вы обрезаете изображение со всех сторон настолько, насколько значение смещения

Thracian 07.08.2023 16:59

И зачем ты снова добавляешь тень?

Thracian 07.08.2023 17:01

Если возможно, не могли бы вы добавить свой ресурс изображения? Или другое похожее изображение с формой круга и высотой?

Thracian 07.08.2023 17:29

Я редактирую свой пост, добавляя изображение, и да, не имеет значения, насколько большим я делаю Круг вокруг

Manuel Lucas 08.08.2023 10:04

Оно делает. Вы должны проверить мой обновленный ответ. Я разместил только с пользовательской формой, но другие тоже работают. Вы можете скопировать пасту и попробовать.

Thracian 08.08.2023 12:25

Возможно, вы не центрируете изображение внутри столбца, это может быть так. Если он не отцентрирован, вы не сможете правильно обрезать, особенно область, нарисованная растровым изображением, меньше контейнера.

Thracian 08.08.2023 12:27

Я немного изменю ваш код. Спасибо !

Manuel Lucas 08.08.2023 12:39

Также помните, что это всего лишь пример, показывающий, что вы можете вырезать часть составного объекта или изображения. Если у вас слишком большое изображение, вы должны поместить offset внутри формы и установить что-то вроде offset = size.width*0.05f, чтобы установить радиус пользовательского круга в процентах. Это может быть лучший подход. Это означает, что вы обрезаете 5% изображения с каждой стороны вместо некоторого предопределенного значения dp.

Thracian 08.08.2023 12:46

Другие вопросы по теме