ปรับแต่งรูปภาพ

คุณปรับแต่งรูปภาพได้โดยใช้พร็อพเพอร์ตี้ใน Image Composable (contentScale, colorFilter) นอกจากนี้ คุณยังใช้ Modifiers ที่มีอยู่ เพื่อใช้เอฟเฟกต์ต่างๆ กับ Image ได้ด้วย โดยใช้ตัวแก้ไขกับ Composable ใดก็ได้ ไม่ใช่แค่ Composable Image เท่านั้น ในขณะที่ contentScale และ colorFilter เป็นพารามิเตอร์ที่ชัดเจนใน Composable Image

ขนาดเนื้อหา

ระบุcontentScaleตัวเลือกเพื่อครอบตัดหรือเปลี่ยนวิธีปรับขนาดรูปภาพภายใน ขอบเขตของรูปภาพ โดยค่าเริ่มต้น หากคุณไม่ได้ระบุcontentScaleตัวเลือก ระบบจะใช้ContentScale.Fit

ในตัวอย่างด้านล่างนี้ เราจำกัด Composable ของรูปภาพให้มีขนาด 150dp พร้อมด้วยเส้นขอบ และตั้งค่าพื้นหลังเป็นสีเหลืองใน Composable ของ 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 portrait ContentScale.Fit landscape
ContentScale.Crop: ครอบตัดรูปภาพตรงกลางให้พอดีกับพื้นที่ที่มี ContentScale.Crop portrait ContentScale.Crop landscape
ContentScale.FillHeight: ปรับขนาดแหล่งที่มาโดยรักษาสัดส่วนการแสดงผลเพื่อให้ขอบเขตตรงกับความสูงของปลายทาง ContentScale.FillHeight portrait ContentScale.FillHeight แนวนอน
ContentScale.FillWidth: ปรับขนาดแหล่งที่มาโดยรักษาสัดส่วนการแสดงผลเพื่อให้ขอบเขตตรงกับความกว้างของปลายทาง ContentScale.FillWidth portrait ContentScale.FillWidth แนวนอน
ContentScale.FillBounds: ปรับขนาดเนื้อหาในแนวตั้งและแนวนอนไม่สม่ำเสมอเพื่อให้เต็มขอบเขตปลายทาง (หมายเหตุ: การดำเนินการนี้จะทำให้รูปภาพบิดเบี้ยวหากคุณวางรูปภาพในคอนเทนเนอร์ที่ไม่ตรงกับสัดส่วนที่แน่นอนของรูปภาพ) ContentScale.FillBounds portrait ContentScale.FillBounds แนวนอน
ContentScale.Inside: ปรับขนาดแหล่งที่มาเพื่อรักษาอัตราส่วนภายในขอบเขตปลายทาง หากแหล่งที่มามีขนาดเล็กกว่าหรือเท่ากับปลายทางในทั้ง 2 มิติ แหล่งที่มาจะทํางานคล้ายกับ `None` โดยเนื้อหาจะอยู่ในขอบเขตเสมอ หากเนื้อหามีขนาดเล็กกว่าขอบเขต ระบบจะไม่ปรับขนาด รูปภาพต้นฉบับใหญ่กว่าขอบเขต ContentScale.Inside portrait, source image larger than bounds รูปภาพต้นฉบับเล็กกว่าขอบเขต ContentScale.Inside portrait, source image smaller than bounds รูปภาพต้นฉบับใหญ่กว่าขอบเขต 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 Composable

การดำเนินการทั่วไปคือการรวม 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) เพื่อระบุสัดส่วนที่กำหนดเองสำหรับรูปภาพ (หรือ Composable ใดก็ได้)

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) ในรูปภาพ

ตัวกรองสี - เปลี่ยนสีพิกเซลของรูปภาพ

Composable ของรูปภาพมีพารามิเตอร์ colorFilter ที่เปลี่ยนเอาต์พุตของ แต่ละพิกเซลของรูปภาพได้

การปรับสีรูปภาพ

การใช้ ColorFilter.tint(color, blendMode) จะใช้โหมดผสมผสานกับสีที่ระบุใน Composable 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 tint with BlendMode.Darken
รูปที่ 8: Color.Green tint with 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 composable

หากต้องการเปลี่ยนคอนทราสต์และความสว่างของรูปภาพ คุณสามารถใช้ 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

สลับสีของ Composable 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 เป็น "ไม่จำกัด" ในรูปภาพด้านบน ขอบของรูปภาพจะเบลอแทนที่จะคมชัด

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