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

আপনি 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-এর ফলে বিভিন্ন প্রভাব পড়ে। যেমন, ছবিতে 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 ব্যবহার করে সবুজ রঙের আভা সহ একটি কুকুর, যার ফলে গাঢ় সবুজ শেড তৈরি হয়।
ছবি ৮. 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.