Bạn có thể tuỳ chỉnh hình ảnh bằng cách sử dụng các thuộc tính trên một thành phần kết hợp Image
(contentScale
, colorFilter
). Bạn cũng có thể áp dụng Modifiers
hiện có để dùng nhiều hiệu ứng cho Image
. Bạn có thể sử dụng đối tượng sửa đổi trên mọi Thành phần kết hợp, không chỉ thành phần kết hợp Image
, mặc dù contentScale
và colorFilter
là các tham số phải khai báo rõ ràng trên thành phần kết hợp Image
.
Phạm vi của nội dung
Hãy chỉ định một tuỳ chọn contentScale
để cắt hoặc điều chỉnh kích thước hình ảnh theo tỷ lệ bên trong giới hạn của hình ảnh đó. Theo mặc định, nếu bạn không chỉ định tuỳ chọn contentScale
, thì ContentScale.Fit
sẽ được sử dụng.
Trong ví dụ bên dưới, thành phần kết hợp Image bị hạn chế ở kích thước 150 dp với đường viền và nền được đặt thành màu vàng trên thành phần kết hợp Image
để hiển thị các tuỳ chọn ContentScale
khác nhau trong bảng dưới đây.
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 )
Việc đặt các tuỳ chọn ContentScale
khác nhau sẽ dẫn đến kết quả khác nhau. Dưới đây là bảng có thể giúp bạn chọn đúng chế độ ContentScale
mà bạn yêu cầu:
Hình ảnh nguồn | ||
ContentScale |
Kết quả – Hình ảnh dọc: | Kết quả – Hình ảnh ngang: |
ContentScale.Fit : Điều chỉnh tỷ lệ hình ảnh một cách đồng nhất, giữ nguyên tỷ lệ khung hình (mặc định). Nếu nội dung nhỏ hơn kích thước, hình ảnh sẽ được tăng kích thước theo tỷ lệ cho vừa với giới hạn. |
||
ContentScale.Crop : Cắt giữa hình ảnh vào khoảng trống có sẵn. |
||
ContentScale.FillHeight : Điều chỉnh theo tỷ lệ nguồn để duy trì tỷ lệ khung hình sao cho các giới hạn khớp với chiều cao đích đến. |
||
ContentScale.FillWidth : Điều chỉnh theo tỷ lệ nguồn để duy trì tỷ lệ khung hình sao cho các giới hạn khớp với chiều rộng đích đến. |
||
ContentScale.FillBounds : Điều chỉnh nội dung theo tỷ lệ một cách không đồng nhất theo chiều dọc và chiều ngang để lấp đầy các giới hạn đích đến. (Lưu ý: Thao tác này sẽ làm méo hình ảnh nếu bạn đặt hình ảnh vào vùng chứa không phù hợp với tỷ lệ chính xác của hình ảnh) |
||
ContentScale.Inside : Điều chỉnh nguồn theo tỷ lệ để duy trì tỷ lệ khung hình bên trong giới hạn đích đến. Nếu nguồn nhỏ hơn hoặc bằng đích đến ở cả hai kích thước, thì tham số sẽ hoạt động tương tự như "None". Nội dung sẽ luôn nằm trong giới hạn. Nếu nội dung nhỏ hơn giới hạn, thì không áp dụng điều chỉnh theo tỷ lệ. |
Hình ảnh nguồn lớn hơn giới hạn: Hình ảnh nguồn nhỏ hơn giới hạn: | Hình ảnh nguồn lớn hơn giới hạn: Hình ảnh nguồn nhỏ hơn giới hạn: |
ContentScale.None : Không điều chỉnh theo tỷ lệ cho nguồn. Nếu nội dung nhỏ hơn giới hạn đích đến, nội dung đó sẽ không được tăng kích thước theo tỷ lệ để phù hợp với khu vực. |
Hình ảnh nguồn lớn hơn giới hạn: Hình ảnh nguồn nhỏ hơn giới hạn: | Hình ảnh nguồn lớn hơn giới hạn: Hình ảnh nguồn nhỏ hơn giới hạn: |
Cắt thành phần kết hợp Image
thành một hình dạng
Để giúp hình ảnh vừa với một hình dạng, hãy sử dụng đối tượng sửa đổi clip
tích hợp sẵn.
Để cắt một hình ảnh thành hình tròn, hãy dùng 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) )
Hình bo tròn – dùng Modifier.clip(RoundedCornerShape(16.dp)
) với kích thước của các góc mà bạn muốn bo tròn:
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)) )
Bạn cũng có thể tạo hình dạng cắt của riêng mình bằng cách mở rộng Shape
và cung cấp một Path
cho hình dạng cần cắt xung quanh:
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()) )
Thêm đường viền vào thành phần kết hợp Image
Một thao tác thường dùng là kết hợp Modifier.border()
với Modifier.clip()
để tạo đường viền xung quanh hình ảnh:
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) )
Nếu muốn tạo đường viền chuyển màu (gradient), bạn có thể sử dụng API Brush
để vẽ đường viền chuyển màu có màu cầu vồng xung quanh hình ảnh:
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) )
Đặt tỷ lệ khung hình tuỳ chỉnh
Để chuyển đổi một hình ảnh thành tỷ lệ khung hình tuỳ chỉnh, hãy sử dụng Modifier.aspectRatio(16f/9f)
để cung cấp tỷ lệ tuỳ chỉnh cho hình ảnh (hoặc bất kỳ thành phần kết hợp nào).
Image( painter = painterResource(id = R.drawable.dog), contentDescription = stringResource(id = R.string.dog_content_description), modifier = Modifier.aspectRatio(16f / 9f) )
Bộ lọc màu – Chuyển đổi màu pixel của hình ảnh
Thành phần kết hợp Image có một tham số colorFilter
có thể thay đổi đầu ra của từng pixel riêng lẻ cho hình ảnh của bạn.
Phủ màu hình ảnh
Việc sử dụng ColorFilter.tint(color, blendMode)
sẽ áp dụng chế độ kết hợp với màu đã cho vào thành phần kết hợp Image
. ColorFilter.tint(color, blendMode)
sử dụng BlendMode.SrcIn
để phủ màu nội dung, nghĩa là màu được cung cấp sẽ hiển thị, tại nơi hình ảnh được hiển thị trên màn hình. Điều này rất hữu ích đối với các biểu tượng và vectơ cần phải có chủ đề khác nhau.
Image( painter = painterResource(id = R.drawable.baseline_directions_bus_24), contentDescription = stringResource(id = R.string.bus_content_description), colorFilter = ColorFilter.tint(Color.Yellow) )
Các kết quả khác của BlendMode
trong các hiệu ứng khác nhau. Chẳng hạn, việc đặt BlendMode.Darken
cùng với Color.Green
trên hình ảnh sẽ tạo ra kết quả sau:
Image( painter = painterResource(id = R.drawable.dog), contentDescription = stringResource(id = R.string.dog_content_description), colorFilter = ColorFilter.tint(Color.Green, blendMode = BlendMode.Darken) )
Xem tài liệu tham khảo về BlendMode để biết thêm thông tin về các chế độ kết hợp khác hiện có.
Áp dụng bộ lọc Image
với ma trận màu
Biến đổi hình ảnh bằng cách sử dụng tuỳ chọn ma trận màu ColorFilter
. Ví dụ: để áp dụng bộ lọc đen trắng trên hình ảnh, bạn có thể sử dụng ColorMatrix
và đặt độ bão hoà thành 0f
.
Image( painter = painterResource(id = R.drawable.dog), contentDescription = stringResource(id = R.string.dog_content_description), colorFilter = ColorFilter.colorMatrix(ColorMatrix().apply { setToSaturation(0f) }) )
Điều chỉnh độ tương phản hoặc độ sáng của thành phần kết hợp Image
Để thay đổi độ tương phản và độ sáng của hình ảnh, bạn có thể sử dụng ColorMatrix
để thay đổi các giá trị:
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)) )
Đảo ngược màu của thành phần kết hợp Image
Để đảo ngược màu của hình ảnh, hãy đặt ColorMatrix
để đảo ngược màu:
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)) )
Làm mờ thành phần kết hợp Image
Để làm mờ hình ảnh, hãy sử dụng Modifier.blur()
, cung cấp radiusX
và radiusY
, trong đó chỉ định bán kính làm mờ theo chiều ngang và chiều dọc tương ứng.
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)) ) )
Khi làm mờ Images
, bạn nên sử dụng BlurredEdgeTreatment(Shape)
thay vì BlurredEdgeTreatment.Unbounded
, vì mã thứ hai dùng để làm mờ kết xuất hình ảnh tuỳ ý theo dự kiến sẽ hiển thị bên ngoài giới hạn của nội dung gốc. Đối với hình ảnh, có khả năng hình ảnh sẽ không hiển thị ngoài giới hạn nội dung; trong khi việc làm mờ hình chữ nhật góc tròn có thể cần sự khác biệt này.
Ví dụ: nếu chúng ta đặt BlurredEdgeTreatment
thành Unbounded trên hình ảnh ở trên, các cạnh của hình ảnh sẽ xuất hiện mờ thay vì sắc nét:
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)) )
Đề xuất cho bạn
- Lưu ý: văn bản có đường liên kết sẽ hiện khi JavaScript tắt
- Đối tượng sửa đổi đồ hoạ
- Hình ảnh xuất hiện khi đang tải {:#loading-images}
- Biểu tượng Material {:#material-icons}