Computer >> บทช่วยสอนคอมพิวเตอร์ >  >> การเขียนโปรแกรม >> Android

วิธีแปลง Drawable เป็น Bitmap ใน Android ด้วย Kotlin

ภาพรวม

ตัวอย่างนี้สาธิตการแปลง Drawable Resource ให้เป็น Bitmap เพื่อนำไปประมวลผลต่อ เช่น บันทึกไฟล์ แชร์ แก้ไขพิกเซล หรืออัปโหลด

ขั้นตอนที่ 1: สร้างโปรเจกต์ใหม่

เปิด Android Studio เลือก File → New Project

ขั้นตอนที่ 2: Layout (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:gravity="center"
    android:orientation="vertical"
    android:padding="16dp"
    tools:context=".MainActivity">

    <ImageView
        android:id="@+id/imageView"
        android:layout_width="200dp"
        android:layout_height="200dp"
        android:scaleType="centerCrop"
        android:src="@drawable/ic_launcher_foreground" />

    <Button
        android:id="@+id/btnConvert"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_marginTop="20dp"
        android:text="Convert Drawable to Bitmap" />

</LinearLayout>

ขั้นตอนที่ 3: MainActivity.kt

import android.graphics.Bitmap
import android.graphics.BitmapFactory
import android.graphics.drawable.BitmapDrawable
import android.graphics.drawable.Drawable
import android.os.Bundle
import android.widget.Button
import android.widget.ImageView
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.graphics.drawable.toBitmap

class MainActivity : AppCompatActivity() {
    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)
        setContentView(R.layout.activity_main)
        title = "KotlinApp"

        val imageView = findViewById<ImageView>(R.id.imageView)
        val btnConvert = findViewById<Button>(R.id.btnConvert)

        btnConvert.setOnClickListener {
            // วิธีที่ 1: ใช้ BitmapFactory (จาก Resource ID)
            val bitmap1 = BitmapFactory.decodeResource(resources, R.drawable.ic_launcher_foreground)
            imageView.setImageBitmap(bitmap1)
            showToast("Method 1: BitmapFactory.decodeResource")

            // วิธีที่ 2: ใช้ Extension Function (Kotlin/KTX) - ต้องเพิ่ม dependency
            // val bitmap2 = resources.getDrawable(R.drawable.ic_launcher_foreground, theme).toBitmap()
            
            // วิธีที่ 3: จาก Drawable ที่มีอยู่ใน ImageView
            val drawable = imageView.drawable
            val bitmap3 = drawableToBitmap(drawable)
            // imageView.setImageBitmap(bitmap3)
        }
    }

    // Helper: แปลง Drawable ใดๆ เป็น Bitmap
    private fun drawableToBitmap(drawable: Drawable?): Bitmap? {
        return when (drawable) {
            null -> null
            is BitmapDrawable -> drawable.bitmap
            else -> {
                val width = drawable.intrinsicWidth
                val height = drawable.intrinsicHeight
                if (width <= 0 || height <= 0) return null
                
                val bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888)
                val canvas = android.graphics.Canvas(bitmap)
                drawable.setBounds(0, 0, canvas.width, canvas.height)
                drawable.draw(canvas)
                bitmap
            }
        }
    }

    private fun showToast(message: String) {
        Toast.makeText(this, message, Toast.LENGTH_SHORT).show()
    }
}

วิธีการแปลง Drawable → Bitmap ทั้งหมด

วิธีโค้ดเหมาะสำหรับ
BitmapFactoryBitmapFactory.decodeResource(res, R.drawable.xxx)Resource ID โดยตรง เร็วที่สุด
Drawable.toBitmap()drawable.toBitmap() (KTX)Drawable object ที่มีอยู่แล้ว
Canvas Drawสร้าง Bitmap + Canvas + drawable.draw()VectorDrawable, LayerDrawable, Custom Drawable
ImageView.getDrawingCache()imageView.drawingCache (Deprecated)ไม่แนะนำใช้แล้ว

Dependency สำหรับ KTX Extension

// build.gradle
dependencies {
    implementation "androidx.core:core-ktx:1.12.0"
    // toBitmap() extension อยู่ใน core-ktx
}

การใช้งาน Bitmap หลังแปลง

// บันทึกไฟล์
val outputStream = FileOutputStream(file)
bitmap.compress(Bitmap.CompressFormat.PNG, 100, outputStream)
outputStream.close()

// แปลงเป็น ByteArray
val byteArray = ByteArrayOutputStream().apply {
    bitmap.compress(Bitmap.CompressFormat.JPEG, 90, this)
}.toByteArray()

// Resize
val resized = Bitmap.createScaledBitmap(bitmap, newWidth, newHeight, true)

// Crop
val cropped = Bitmap.createBitmap(bitmap, x, y, width, height)

ขั้นตอนที่ 4: Manifest

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="https://schemas.android.com/apk/res/android"
    package="com.example.drawabletobitmap">
    <application ... >
        <activity android:name=".MainActivity"> ... </activity>
    </application>
</manifest>

การทดสอบ

รันแอป กดปุ่ม "Convert Drawable to Bitmap" รูปใน ImageView จะถูกแปลงและแสดงใหม่ (ดูไม่ต่างกันแต่มาเป็น Bitmap แล้ว)