एंड्रॉइड में Drawable को Bitmap में बदलना
यह उदाहरण दर्शाता है कि BitmapFactory और Drawable एक्सटेंशन का उपयोग करके ड्रॉएबल संसाधन को बिटमैप में कैसे परिवर्तित किया जाए।
चरण 1: नया प्रोजेक्ट बनाएं
एंड्रॉइड स्टूडियो में File → New Project चुनें।
चरण 2: लेआउट (activity_main.xml)
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="https://schemas.android.com/apk/res/android"
xmlns:tools="https://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
android:gravity="center"
android:padding="16dp"
tools:context=".MainActivity">
<ImageView
android:id="@+id/imageView"
android:layout_width="200dp"
android:layout_height="200dp"
android:layout_marginBottom="24dp"
android:scaleType="centerCrop"
android:contentDescription="परिवर्तित छवि" />
<Button
android:id="@+id/btnConvert"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:text="Drawable को Bitmap में बदलें"
android:textSize="16sp" />
<Button
android:id="@+id/btnConvertAdvanced"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_marginTop="8dp"
android:text="उन्नत रूपांतरण (Vector/Animated)"
android:textSize="16sp" />
<TextView
android:id="@+id/textViewInfo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="16dp"
android:text="जानकारी यहां दिखेगी"
android:textSize="14sp"
android:textAlignment="center" />
</LinearLayout>
चरण 3: MainActivity.kt
import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.Canvas
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.graphics.drawable.VectorDrawable
import android.os.Build
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.TextView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.drawable.DrawableCompat
class MainActivity : AppCompatActivity() {
private lateinit var imageView: ImageView
private lateinit var btnConvert: Button
private lateinit var btnConvertAdvanced: Button
private lateinit var textViewInfo: TextView
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
title = "KotlinApp"
imageView = findViewById(R.id.imageView)
btnConvert = findViewById(R.id.btnConvert)
btnConvertAdvanced = findViewById(R.id.btnConvertAdvanced)
textViewInfo = findViewById(R.id.textViewInfo)
// मूल रूपांतरण
btnConvert.setOnClickListener { convertBasic() }
// उन्नत रूपांतरण (VectorDrawable, AnimatedVectorDrawable समर्थन)
btnConvertAdvanced.setOnClickListener { convertAdvanced() }
}
// विधि 1: BitmapFactory (सबसे सरल, केवल BitmapDrawable के लिए)
private fun convertBasic() {
try {
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.your_image)
imageView.setImageBitmap(bitmap)
textViewInfo.text = "आकार: ${bitmap.width}x${bitmap.height}px, कॉन्फ़िग: ${bitmap.config}"
Toast.makeText(this, "बिटमैप में बदला गया", Toast.LENGTH_SHORT).show()
} catch (e: Exception) {
Toast.makeText(this, "त्रुटि: ${e.message}", Toast.LENGTH_SHORT).show()
}
}
// विधि 2: सार्वभौमिक रूपांतरण (सभी Drawable प्रकारों के लिए काम करता है)
private fun convertAdvanced() {
val drawable = resources.getDrawable(R.drawable.your_image, theme)
val bitmap = drawableToBitmap(drawable)
bitmap?.let {
imageView.setImageBitmap(it)
textViewInfo.text = "प्रकार: ${drawable.javaClass.simpleName}\nआकार: ${it.width}x${it.height}px"
Toast.makeText(this, "उन्नत रूपांतरण सफल", Toast.LENGTH_SHORT).show()
} ?: run {
Toast.makeText(this, "रूपांतरण विफल", Toast.LENGTH_SHORT).show()
}
}
// सार्वभौमिक Drawable → Bitmap रूपांतरण
private fun drawableToBitmap(drawable: Drawable?): Bitmap? {
return drawable?.let { draw ->
// यदि पहले से BitmapDrawable है, तो सीधे बिटमैप प्राप्त करें
if (draw is BitmapDrawable) {
return@let draw.bitmap
}
// आंतरिक आकार प्राप्त करें
val width = if (draw.intrinsicWidth > 0) draw.intrinsicWidth else 100
val height = if (draw.intrinsicHeight > 0) draw.intrinsicHeight else 100
// म्यूटेबल बिटमैप बनाएं
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
// ड्रॉएबल बाउंड्स सेट करें और ड्रा करें
draw.setBounds(0, 0, canvas.width, canvas.height)
draw.draw(canvas)
bitmap
}
}
}
चरण 4: एक्सटेंशन फ़ंक्शन (पुन: प्रयोज्य)
import android.graphics.Bitmap
import android.graphics.Canvas
import android.graphics.drawable.Drawable
import androidx.core.graphics.drawable.DrawableCompat
// Drawable एक्सटेंशन
fun Drawable.toBitmap(): Bitmap? {
return if (this is BitmapDrawable) {
this.bitmap
} else {
val width = if (intrinsicWidth > 0) intrinsicWidth else 1
val height = if (intrinsicHeight > 0) intrinsicHeight else 1
val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
setBounds(0, 0, canvas.width, canvas.height)
draw(canvas)
bitmap
}
}
// VectorDrawable के लिए विशेष हैंडलिंग (API 21+)
@RequiresApi(Build.VERSION_CODES.LOLLIPOP)
fun VectorDrawable.toBitmap(tintColor: Int? = null): Bitmap {
val bitmap = Bitmap.createBitmap(intrinsicWidth, intrinsicHeight, Bitmap.Config.ARGB_8888)
val canvas = Canvas(bitmap)
// टिंट लागू करें यदि प्रदान किया गया
tintColor?.let {
DrawableCompat.setTint(this, it)
}
setBounds(0, 0, canvas.width, canvas.height)
draw(canvas)
return bitmap
}
// उपयोग:
// val bitmap = resources.getDrawable(R.drawable.ic_icon, theme).toBitmap()
// val bitmap = (resources.getDrawable(R.drawable.vector_icon, theme) as VectorDrawable).toBitmap(Color.RED)
चरण 5: AndroidManifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
package="com.example.drawabletobitmap">
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
रूपांतरण विधियों की तुलना:
| विधि | समर्थित प्रकार | प्रदर्शन | उपयोग का मामला |
|---|---|---|---|
BitmapFactory.decodeResource | केवल बिटमैप संसाधन (PNG, JPG, WebP) | तेज़ | सरल छवि संसाधन |
BitmapDrawable.bitmap | BitmapDrawable | तत्काल | जब आप जानते हैं कि यह बिटमैप है |
Canvas.draw() | सभी (Vector, Shape, Layer, Animated) | धीमा (आवंटन) | सार्वभौमिक समाधान |
Drawable.toBitmap() एक्सटेंशन | सभी | धीमा | पुन: प्रयोज्य, साफ कोड |
सामान्य उपयोग के मामले:
- छवि साझाकरण: बिटमैप को साझा करने के लिए फ़ाइल के रूप में सहेजें
- छवि प्रसंस्करण: फिल्टर, क्रॉप, रिसाइज़ लागू करें
- कस्टम व्यू: कस्टम ड्राइंग में बिटमैप के रूप में ड्रॉएबल का उपयोग करें
- नोटिफिकेशन: बड़े आइकन के लिए बिटमैप आवश्यक
- कैशिंग: ड्रॉएबल की तुलना में बिटमैप को कैश करना आसान
मेमोरी प्रबंधन:
// बड़े बिटमैप के लिए inSampleSize का उपयोग करें
fun decodeSampledBitmapFromResource(
res: Resources,
resId: Int,
reqWidth: Int,
reqHeight: Int
): Bitmap {
val options = BitmapFactory.Options().apply {
inJustDecodeBounds = true
BitmapFactory.decodeResource(res, resId, this)
}
options.inSampleSize = calculateInSampleSize(options, reqWidth, reqHeight)
options.inJustDecodeBounds = false
return BitmapFactory.decodeResource(res, resId, options)
}
fun calculateInSampleSize(options: BitmapFactory.Options, reqWidth: Int, reqHeight: Int): Int {
var inSampleSize = 1
if (options.outHeight > reqHeight || options.outWidth > reqWidth) {
val halfH = options.outHeight / 2
val halfW = options.outWidth / 2
while ((halfH / inSampleSize) >= reqHeight && (halfW / inSampleSize) >= reqWidth) {
inSampleSize *= 2
}
}
return inSampleSize
}