কাস্টম পেইন্টার

কম্পোজে, একটি Painter অবজেক্ট এমন কিছু উপস্থাপন করতে ব্যবহৃত হয় যা আঁকা যায় (অ্যান্ড্রয়েডে সংজ্ঞায়িত Drawable এপিআই-এর একটি বিকল্প) এবং এটি ব্যবহারকারী সংশ্লিষ্ট কম্পোজেবলের পরিমাপ ও লেআউটকে প্রভাবিত করে। একটি BitmapPainter একটি ImageBitmap গ্রহণ করে যা স্ক্রিনে একটি Bitmap আঁকতে পারে।

বেশিরভাগ ক্ষেত্রে, উপরে উল্লিখিত painterResource() ব্যবহার করলে অ্যাসেটটির জন্য সঠিক পেইন্টার (যেমন BitmapPainter বা VectorPainter ) রিটার্ন হয়। এই দুটির মধ্যে পার্থক্য সম্পর্কে আরও তথ্যের জন্য - ImageBitmap বনাম ImageVector বিভাগটি পড়ুন।

Painter DrawModifier থেকে ভিন্ন, যা কঠোরভাবে তাকে দেওয়া সীমার মধ্যেই অঙ্কন করে এবং কম্পোজেবলের পরিমাপ বা বিন্যাসের উপর এর কোনো প্রভাব থাকে না।

একটি কাস্টম পেইন্টার তৈরি করতে, Painter ক্লাসটি এক্সটেন্ড করুন এবং onDraw মেথডটি ইমপ্লিমেন্ট করুন, যা কাস্টম গ্রাফিক্স আঁকার জন্য DrawScope এ অ্যাক্সেস দেয়। এছাড়াও আপনি intrinsicSize ওভাররাইড করতে পারেন, যা এটির অন্তর্ভুক্ত Composable-কে প্রভাবিত করতে ব্যবহৃত হবে।

class OverlayImagePainter constructor(
    private val image: ImageBitmap,
    private val imageOverlay: ImageBitmap,
    private val srcOffset: IntOffset = IntOffset.Zero,
    private val srcSize: IntSize = IntSize(image.width, image.height),
    private val overlaySize: IntSize = IntSize(imageOverlay.width, imageOverlay.height)
) : Painter() {

    private val size: IntSize = validateSize(srcOffset, srcSize)
    override fun DrawScope.onDraw() {
        // draw the first image without any blend mode
        drawImage(
            image,
            srcOffset,
            srcSize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            )
        )
        // draw the second image with an Overlay blend mode to blend the two together
        drawImage(
            imageOverlay,
            srcOffset,
            overlaySize,
            dstSize = IntSize(
                this@onDraw.size.width.roundToInt(),
                this@onDraw.size.height.roundToInt()
            ),
            blendMode = BlendMode.Overlay
        )
    }

    /**
     * Return the dimension of the underlying [ImageBitmap] as it's intrinsic width and height
     */
    override val intrinsicSize: Size get() = size.toSize()

    private fun validateSize(srcOffset: IntOffset, srcSize: IntSize): IntSize {
        require(
            srcOffset.x >= 0 &&
                srcOffset.y >= 0 &&
                srcSize.width >= 0 &&
                srcSize.height >= 0 &&
                srcSize.width <= image.width &&
                srcSize.height <= image.height
        )
        return srcSize
    }
}

এখন যেহেতু আমাদের নিজস্ব Painter তৈরি হয়ে গেছে, আমরা নিচের পদ্ধতি অনুসরণ করে আমাদের মূল ছবির উপর যেকোনো ছবি বসিয়ে দিতে পারি:

val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow)
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog)
val customPainter = remember {
    OverlayImagePainter(dogImage, rainbowImage)
}
Image(
    painter = customPainter,
    contentDescription = stringResource(id = R.string.dog_content_description),
    contentScale = ContentScale.Crop,
    modifier = Modifier.wrapContentSize()
)

কাস্টম পেইন্টার ব্যবহার করে দুটি ছবি একত্রিত করার ফলাফল নিচে দেখা যাচ্ছে:

কাস্টম পেইন্টার যা দুটি ছবিকে একটির উপর আরেকটি বসিয়ে দেয়।
চিত্র ১ : কাস্টম পেইন্টার যা দুটি ছবিকে একটির উপর আরেকটি স্থাপন করে।

Modifier.paint(customPainter) এর সাথে একটি কাস্টম পেইন্টার ব্যবহার করেও নিম্নলিখিতভাবে একটি কম্পোজেবলে কন্টেন্ট আঁকা যেতে পারে:

val rainbowImage = ImageBitmap.imageResource(id = R.drawable.rainbow)
val dogImage = ImageBitmap.imageResource(id = R.drawable.dog)
val customPainter = remember {
    OverlayImagePainter(dogImage, rainbowImage)
}
Box(
    modifier =
    Modifier.background(color = Color.Gray)
        .padding(30.dp)
        .background(color = Color.Yellow)
        .paint(customPainter)
) { /** intentionally empty **/ }

{% হুবহু %} {% endverbatim %} {% হুবহু %} {% endverbatim %}