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

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

ระดับเนื้อหา

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

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

ตัดคลิป 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: ตัดคลิปออกและใส่เส้นขอบรอบๆ

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

วันที่ สี.สีเขียวย้อมด้วย BlendMode.Darken
ภาพที่ 8: สี สีเขียวอ่อนด้วย 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 (ภาพขาวดำ)

ปรับคอนทราสต์หรือความสว่างของ Composable 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 Composable

หากต้องการสลับสีของรูปภาพ ให้ตั้งค่า 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 Composable

หากต้องการเบลอรูปภาพ ให้ใช้ 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 ไม่มีการควบคุม
รูปที่ 13: BlurEdgeTreatment.Unbounded