इमेज को पसंद के मुताबिक बनाना

किसी Image कंपोज़ेबल पर मौजूद प्रॉपर्टी (जैसे, contentScale, colorFilter) इस्तेमाल करके, इमेज पसंद के मुताबिक बनाई जा सकती हैं. Image पर अलग-अलग इफ़ेक्ट लागू करने के लिए, मौजूदा मॉडिफ़ायर भी इस्तेमाल किए जा सकते हैं. मॉडिफ़ायर, Image कंपोज़ेबल पर ही नहीं, बल्कि हर कंपोज़ेबल पर इस्तेमाल किए जा सकते हैं. वहीं, contentScale और colorFilter खास तौर पर Image कंपोज़ेबल के लिए ही बनाए गए पैरामीटर हैं.

कॉन्टेंट स्केल

किसी इमेज को काटने या उसका साइज़ बदलने का तरीका तय करने के लिए, contentScale विकल्प का इस्तेमाल करें. डिफ़ॉल्ट रूप से, अगर आपने कोई contentScale विकल्प नहीं चुना है, तो ContentScale.Fit का इस्तेमाल किया जाएगा.

यहां दिए गए उदाहरण में, Image कंपोज़ेबल को 150 डीपी साइज़ तक सीमित किया गया है और इसमें बॉर्डर भी जोड़ा गया है. इसके अलावा, 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.Crop: इमेज को बॉक्स में पूरी तरह फ़िट करने के लिए, उसके किनारे काट दिए जाते हैं और बीच का हिस्सा दिखाया जाता है. स्क्वेयर फ़्रेम को भरने के लिए, पोर्ट्रेट इमेज को काटा गया है. इसमें इमेज का सिर्फ़ बीच वाला हिस्सा दिख रहा है. स्क्वेयर फ़्रेम को भरने के लिए, लैंडस्केप इमेज को काटा गया है. इसमें इमेज का सिर्फ़ बीच वाला हिस्सा दिख रहा है.
ContentScale.FillHeight: इमेज की आसपेक्ट रेशियो को बदले बिना, उसे ऐसे स्केल करता है कि उसकी ऊंचाई बिलकुल बॉक्स की ऊंचाई के बराबर हो जाए. एक पोर्ट्रेट इमेज, जिसे चौकोर फ़्रेम की ऊंचाई के हिसाब से स्केल किया गया है. इसमें पूरी इमेज दिख रही है. साथ ही, बाईं और दाईं ओर पीला बैकग्राउंड दिख रहा है. एक लैंडस्केप इमेज, जिसे स्क्वेयर फ़्रेम की ऊंचाई के हिसाब से स्केल किया गया है. साथ ही, इसके किनारों को काटा गया है.
ContentScale.FillWidth: इमेज की आसपेक्ट रेशियो को बदले बिना, उसे ऐसे स्केल करता है कि उसकी चौड़ाई बिलकुल बॉक्स की चौड़ाई के बराबर हो जाए. स्क्वेयर फ़्रेम की चौड़ाई के हिसाब से पोर्ट्रेट इमेज को स्केल किया गया है. इसमें ऊपर और नीचे के हिस्से को काटा गया है. लैंडस्केप इमेज को स्क्वेयर फ़्रेम की चौड़ाई के हिसाब से स्केल किया गया है. इसमें पूरी इमेज दिख रही है. साथ ही, ऊपर और नीचे की ओर पीले रंग का बैकग्राउंड दिख रहा है.
ContentScale.FillBounds: इमेज को वर्टिकल और हॉरिज़ॉन्टल तौर पर असमान रूप से खींचकर, उसे बॉक्स के बराबर साइज़ का कर दिया जाता है. (ध्यान दें: अगर इमेज ऐसे कंटेनर में रखी जाती हैं जो उनके आसपेक्ट रेशियो से मेल नहीं खाते हैं, तो इमेज खराब हो जाएंगी). एक पोर्ट्रेट इमेज को इस तरह से बिगाड़ा गया है कि वह स्क्वेयर फ़्रेम में पूरी तरह से फ़िट हो जाए. इससे इमेज स्ट्रेच हो जाती है. लैंडस्केप इमेज को स्क्वेयर फ़्रेम में पूरी तरह से फ़िट करने के लिए, उसे स्ट्रेच करके दिखाया गया है.
ContentScale.Inside: इमेज को इस हिसाब से स्केल किया जाता है कि उसकी आसपेक्ट रेशियो न बदले और वह बॉक्स के अंदर भी रहे. अगर इमेज, लंबाई और चौड़ाई दोनों में बॉक्स से छोटी या उसके बराबर है, तो यह 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 की मदद से इमेज को क्लिप करना.

गोल किनारों वाली शेप के लिए, 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 की मदद से इमेज को क्लिप करना.

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())
)

स्क्वेयर इमेज में कुत्ते को कस्टम ओवल शेप में क्लिप किया गया है.
तीसरी इमेज. इस इमेज में, कस्टम पाथ शेप का इस्तेमाल करके इमेज को क्लिप किया गया है.

किसी 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)
)

स्क्वेयर इमेज में एक कुत्ते को दिखाया गया है. इसे गोल आकार में काटा गया है. गोल आकार के चारों ओर पीले रंग का बॉर्डर है.
चौथी इमेज. क्लिप की गई इमेज, जिसके चारों ओर बॉर्डर है.

ग्रेडिएंट बॉर्डर बनाने के लिए, 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)
)

एक कुत्ते की गोल इमेज, जिसके चारों ओर रेनबो ग्रेडिएंट बॉर्डर है.
पांचवीं इमेज. रेनबो ग्रेडिएंट सर्कल बॉर्डर.

अपनी पसंद के मुताबिक आसपेक्ट रेशियो सेट करना

किसी इमेज का आसपेक्ट रेशियो अपनी पसंद के मुताबिक सेट करने के लिए, Modifier.aspectRatio(16f/9f) का इस्तेमाल करें. इससे किसी इमेज (या किसी भी कंपोज़ेबल) के लिए, पसंद के मुताबिक रेशियो सेट किया जा सकता है.

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

एक कुत्ते की स्क्वेयर इमेज, जिसे 16:9 के आसपेक्ट रेशियो में बदल दिया गया है. इससे इमेज चौड़ी और छोटी हो गई है.
छठी इमेज. Image पर Modifier.aspectRatio(16f/9f) का इस्तेमाल करना.

कलर फ़िल्टर: इमेज के पिक्सल के रंग बदलना

Image कंपोज़ेबल में 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 के साथ लागू किया गया.

अन्य BlendMode से अलग-अलग इफ़ेक्ट मिलते हैं. उदाहरण के लिए, किसी इमेज पर Color.Green के साथ BlendMode.Darken सेट करने पर, यह नतीजा मिलता है:

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 का इस्तेमाल करके कुत्ते की इमेज पर हरे रंग का टिंट लगाया गया है. इससे, हरे रंग के गहरे शेड मिलते हैं.
आठवीं इमेज. 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) })
)

काले और सफ़ेद रंग के फ़िल्टर वाली कुत्ते की इमेज. इसमें सभी रंगों को हटा दिया गया है.
नौवीं इमेज. Color Matrix with saturation 0 (black and white image).

किसी 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))
)

एक कुत्ते की इमेज, जिसमें चमक और कंट्रास्ट को बढ़ाया गया है. इससे इमेज ज़्यादा साफ़ दिख रही है.
दसवीं इमेज. Adjusted image brightness and contrast using 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. BlurEffect को किसी इमेज पर लागू किया गया है.

Images ब्लर करते समय, BlurredEdgeTreatment.Unbounded के बजाय BlurredEdgeTreatment(Shape) का इस्तेमाल करने का सुझाव दिया जाता है. ऐसा इसलिए, क्योंकि इसका इस्तेमाल उन रेंडरिंग को धुंधला करने के लिए किया जाता है जिन्हें ओरिजनल कॉन्टेंट की सीमाओं से बाहर रेंडर किया जाना चाहिए. इमेज के मामले में, ऐसा हो सकता है कि वे बॉक्स के बाहर रेंडर न हों. वहीं, गोल कोनों वाले आयताकार को धुंधला करने के लिए, इस अंतर की ज़रूरत पड़ सकती है.

उदाहरण के लिए, अगर हम पिछली इमेज में 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.