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

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

ขนาดเนื้อหา

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

ในตัวอย่างต่อไปนี้ Image Composable จะจำกัดขนาดไว้ที่ 150dp พร้อมเส้นขอบ และตั้งค่าพื้นหลังเป็นสีเหลืองใน Image Composable เพื่อ แสดง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.Crop: ครอบตัดรูปภาพตรงกลางให้พอดีกับพื้นที่ที่มี รูปภาพแนวตั้งที่ครอบตัดให้เต็มกรอบสี่เหลี่ยม โดยแสดงเฉพาะส่วนกลางของรูปภาพ รูปภาพแนวนอนที่ครอบตัดให้เต็มเฟรมสี่เหลี่ยม โดยแสดงเฉพาะส่วนกลางของรูปภาพ
ContentScale.FillHeight: ปรับขนาดแหล่งที่มาโดยรักษาสัดส่วนการแสดงผลเพื่อให้ขอบเขตตรงกับความสูงของปลายทาง รูปภาพแนวตั้งที่ปรับขนาดให้เต็มความสูงของกรอบสี่เหลี่ยมจัตุรัส โดยแสดงรูปภาพทั้งหมดที่มีพื้นหลังสีเหลืองที่มองเห็นได้ทางด้านซ้ายและขวา รูปภาพแนวนอนที่ปรับขนาดให้เต็มความสูงของกรอบสี่เหลี่ยมจัตุรัส โดยมีการครอบตัดด้านข้าง
ContentScale.FillWidth: ปรับขนาดแหล่งที่มาโดยรักษาสัดส่วนการแสดงผลเพื่อให้ขอบเขตตรงกับความกว้างของปลายทาง รูปภาพแนวตั้งที่ปรับขนาดให้เต็มความกว้างของกรอบสี่เหลี่ยมจัตุรัส โดยครอบตัดด้านบนและด้านล่าง รูปภาพแนวนอนที่ปรับขนาดให้เต็มความกว้างของกรอบสี่เหลี่ยมจัตุรัส โดยแสดงรูปภาพทั้งหมดที่มีพื้นหลังสีเหลืองที่มองเห็นได้ที่ด้านบนและด้านล่าง
ContentScale.FillBounds: ปรับขนาดเนื้อหาในแนวตั้งและแนวนอนแบบไม่สม่ำเสมอเพื่อให้เต็มขอบเขตปลายทาง (หมายเหตุ: การดำเนินการนี้จะบิดเบือนรูปภาพหากคุณวางรูปภาพในคอนเทนเนอร์ที่ไม่ตรงกับสัดส่วนที่แน่นอนของรูปภาพ) รูปภาพแนวตั้งที่บิดเบี้ยวให้เต็มกรอบสี่เหลี่ยมจัตุรัสโดยการยืดรูปภาพ รูปภาพแนวนอนที่บิดเบี้ยวจนเต็มกรอบสี่เหลี่ยมจัตุรัสโดยการยืดรูปภาพ
ContentScale.Inside: ปรับขนาดแหล่งที่มาเพื่อรักษาอัตราส่วนภายในขอบเขตปลายทาง หากแหล่งที่มามีขนาดเล็กกว่าหรือเท่ากับปลายทางในทั้ง 2 มิติ แหล่งที่มาจะทำงานคล้ายกับ 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)
)

รูปภาพสุนัขที่ตัดเป็นวงกลมที่สมบูรณ์แบบ
รูปที่ 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))
)

รูปภาพสี่เหลี่ยมจัตุรัสของสุนัขที่ตัดขอบให้โค้งมน
รูปที่ 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)
)

รูปภาพสี่เหลี่ยมจัตุรัสของสุนัขที่แปลงเป็นสัดส่วนภาพ 16:9 ทำให้รูปภาพกว้างขึ้นและสั้นลง
รูปที่ 6 การใช้ Modifier.aspectRatio(16f/9f) ใน Image

ฟิลเตอร์สี: เปลี่ยนสีพิกเซลของรูปภาพ

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

แต่งสีรูปภาพ

การใช้ ColorFilter.tint(color, blendMode) จะใช้โหมดผสมผสานกับสีที่ระบุใน Image Composable 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)
)

รูปภาพรถบัสที่มีการใช้สีเหลือง
รูปที่ 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 Color.Green tint ด้วย 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) })
)

สุนัขที่ใช้ฟิลเตอร์ขาวดำ ซึ่งจะนำความอิ่มตัวของสีทั้งหมดออก
รูปที่ 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))
)

สุนัขที่มีความสว่างและคอนทราสต์เพิ่มขึ้น ทำให้ดูสดใสยิ่งขึ้น
รูปที่ 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))
        )
)

สุนัขที่มีเอฟเฟกต์เบลออย่างชัดเจน ทำให้ดูไม่ชัดและไม่โฟกัส
รูปที่ 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))
)

รูปภาพสุนัขเบลอ โดยความเบลอขยายออกไปนอกขอบเขตของรูปภาพเดิม ทำให้ขอบเบลอ
รูปที่ 13 BlurEdgeTreatment.Unbounded