ছবি কাস্টমাইজ করা

আপনি Image কম্পোজ করা যায় (contentScale, colorFilter) এমন আইটেমের প্রপার্টি ব্যবহার করে ছবি কাস্টমাইজ করতে পারবেন। এছাড়াও, আপনার Image-এ বিভিন্ন এফেক্ট প্রয়োগ করতে, আগে থেকে থাকা মডিফায়ার প্রয়োগ করতে পারবেন। Image কম্পোজ করার উপযুক্ত আইটেমের ক্ষেত্রে contentScale ও colorFilter হল স্পষ্ট প্যারামিটার, তবে যেকোনও কম্পোজ করার উপযুক্ত আইটেমের ক্ষেত্রে মডিফায়ার ব্যবহার করা যেতে পারে, শুধু Image কম্পোজ করার উপযুক্ত আইটেমের ক্ষেত্রে নয়।

কন্টেন্ট স্কেল

ছবির বাউন্ডের মধ্যে ছবি কীভাবে স্কেল করা হবে তা ক্রপ বা পরিবর্তন করতে contentScale বিকল্প নির্দিষ্ট করুন। ডিফল্ট হিসেবে, আপনি কোনও contentScale বিকল্প উল্লেখ না করলে, ContentScale.Fit ব্যবহার করা হয়।

নিচের উদাহরণে, Image কম্পোজ করার উপযুক্ত আইটেমকে ১৫০dp সাইজের মধ্যে সীমাবদ্ধ রাখা হয়েছে এবং একটি বর্ডার দেওয়া হয়েছে। 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 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)
)

বৃত্তাকার ছবির মধ্যে একটি কুকুরের ছবি, যার চারপাশে বৃত্তাকার আকৃতির মধ্যে একটি রামধনু গ্রেডিয়েন্ট বর্ডার রয়েছে।
ছবি ৫. রেনবো গ্রেডিয়েন্ট বৃত্তাকার বর্ডার।

কাস্টম অ্যাস্পেক্ট রেশিও সেট করা

কোনও ছবিকে কাস্টম অ্যাস্পেক্ট রেশিওতে ট্রান্সফর্ম করতে, ছবির (বা কোনও কম্পোজ করার উপযুক্ত) জন্য কাস্টম রেশিও প্রদান করতে Modifier.aspectRatio(16f/9f) ব্যবহার করুন।

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

একটি কুকুরের বর্গাকার ছবি, ১৬:৯ অ্যাস্পেক্ট রেশিওতে ট্রান্সফর্ম করা হয়েছে, ফলে এটি আরও চওড়া ও ছোট হয়ে গেছে।
ছবি ৬. 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-এর ফলে আলাদা আলাদা প্রভাব পড়ে। যেমন, কোনও ছবির উপর 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 ব্যবহার করে সবুজ রঙের টিংট প্রয়োগ করা একটি কুকুর, যার ফলে আরও গাঢ় সবুজ শেড তৈরি হয়েছে।
ছবি ৮. BlendMode.Darken-এর সাথে Color.Green tint.

উপলভ্য বিভিন্ন ব্লেন্ড মোড সম্পর্কে আরও তথ্য পেতে, 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) })
)

কালো ও সাদা ফিল্টার প্রয়োগ করা একটি কুকুর, যা সব কালার স্যাচুরেশন সরিয়ে দেয়।
ছবি ৯. স্যাচুরেশন ০ (সাদা-কালো ছবি) সহ কালার ম্যাট্রিক্স।

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
ব্যবহার করে ছবির উজ্জ্বলতা ও কনট্রাস্ট অ্যাডজাস্ট করা হয়েছে।

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

একটি কুকুরের রঙ ইনভার্ট করা হয়েছে, যার ফলে নেগেটিভের মতো এফেক্ট দেখা যাচ্ছে।
ছবি ১১. ছবির রঙ উল্টে গেছে।

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

একটি কুকুরের ছবিতে শক্তিশালী ব্লার এফেক্ট প্রয়োগ করা হয়েছে, যার ফলে সেটি অস্পষ্ট ও ফোকাসের বাইরে দেখাচ্ছে।
ছবি ১২. 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))
)

কুকুরের একটি অস্পষ্ট ছবি, যেখানে অস্পষ্টতা মূল ছবির সীমানা ছাড়িয়ে গেছে, ফলে ছবির প্রান্তগুলি অস্পষ্ট হয়ে গেছে।
ছবি ১৩. BlurEdgeTreatment.Unbounded.