התאמה אישית של תמונה

אפשר להתאים אישית תמונות באמצעות מאפיינים ב-Image שאפשר ליצור ממנו קומפוזיציות (contentScale, colorFilter). אפשר גם להחיל את Modifiers הקיים כדי להחיל אפקטים שונים על ה-Image. אפשר להשתמש במגבילי התאמה בכל סוג של קומפוזבילי, לא רק התוכן הקומפוזבילי Image, ואילו contentScale וגם colorFilter הם פרמטרים מפורשים בתוכן הקומפוזבילי Image.

התאמת התוכן

מציינים אפשרות contentScale כדי לחתוך תמונה או לשנות את אופן שינוי התמונה בהתאם למגבלות שלה. כברירת מחדל, אם לא מציינים אפשרות ל-contentScale, המערכת תשתמש ב-ContentScale.Fit.

בדוגמה הבאה, התוכן הקומפוזבילי של תמונה מוגבל לגודל של 150dp עם מאפיין הגבול והרקע מוגדרים לצהוב בתוכן הקומפוזבילי של 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 לרוחב
ContentScale.Crop: חיתוך התמונה למרכז המרחב הזמין. ContentScale.Crop portrait ContentScale.חיתוך לרוחב
ContentScale.FillHeight: שינוי קנה המידה של המקור תוך שמירה על יחס הגובה-רוחב, כך שהגבולות יהיו תואמים לגובה היעד. ContentScale.FillHeight portrait ContentScale.FillHeight לרוחב
ContentScale.FillWidth: שינוי קנה המידה של המקור תוך שמירה על יחס הגובה-רוחב, כך שהגבולות יהיו תואמים לרוחב היעד. ContentScale.FillWidth portrait ContentScale.FillWidth לרוחב
ContentScale.FillBounds: שינוי קנה המידה של התוכן באופן לא אחיד אנכית ואופקית כדי למלא את גבולות היעד. (הערה: תמונות יעוותו אם תציבו אותן במאגרים שלא תואמים ליחס המדויק של התמונה) ContentScale.FillBounds לאורך ContentScale.FillBounds לרוחב
ContentScale.Inside: שינוי קנה המידה של המקור כדי לשמור על יחס גובה-רוחב בתוך גבולות היעד. אם המקור קטן מהיעד או שווה לו בשני המימדים, הוא מתנהג באופן דומה ל-None. התוכן תמיד יהיה בתוך הגבולות. אם התוכן קטן מהגבולות, לא תתבצע התאמה לעמודה. תמונת המקור גדולה מהגבולות: ContentScale.בפנים לאורך, תמונת המקור גדולה מהגבולות תמונת המקור קטנה מהגבולות: ContentScale.בפנים לאורך, תמונת המקור קטנה מגבולות תמונת המקור גדולה מהגבולות: ContentScale.Inside landscape, source image larger than bounds תמונת המקור קטנה מהגבולות: ContentScale.Inside landscape, source image smaller than bounds
ContentScale.None: לא מחילים שינוי קנה מידה על המקור. אם התוכן קטן מגבולות היעד, הוא לא יוגדל כדי להתאים לאזור. תמונת המקור גדולה מהגבולות: ContentScale.ללא לאורך, תמונת מקור גדולה מהגבולות תמונת המקור קטנה מהגבולות: ContentScale.None portrait, source image smaller than bounds תמונת המקור גדולה מהגבולות: 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)
)

חיתוך תמונה באמצעות צורת עיגול
איור 1: חיתוך תמונה באמצעות עיגול מעוגל

צורה עם פינות מעוגלות – משתמשים ב-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))
)

חיתוך תמונה באמצעות RoundedCorner shape
איור 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

פעולה נפוצה היא לשלב את 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) כדי לספק יחס גובה-רוחב של תמונה (או כל תמונה אחרת) קומפוזבילי למטרה הזו).

Image(
    painter = painterResource(id = R.drawable.dog),
    contentDescription = stringResource(id = R.string.dog_content_description),
    modifier = Modifier.aspectRatio(16f / 9f)
)

שימוש ב-Modifier.aspectRatio(16f/9f) ב-Image
איור 6: שימוש ב-Modifier.aspectRatio(16f/9f) בתמונה

מסנן צבעים – שינוי צבעי הפיקסלים של התמונה

בתמונה הקומפוזבילית של התמונה יש פרמטר colorFilter שיכול לשנות את הפלט של פיקסלים נפרדים של התמונה.

כוונון של תמונה

שימוש ב-ColorFilter.tint(color, blendMode) יחיל מצב שילוב עם שנתתם צבע לתוכן הקומפוזבילי 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 (תמונה בשחור-לבן)

התאמת הניגודיות או הבהירות של תוכן קומפוזבילי מסוג 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

כדי להפוך את הצבעים של תמונה, מגדירים את הסמל 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: אפקט טשטוש מוחל על התמונה

כשמטושטשים את 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: הטיפול בטשטוש.ללא גבולות