package com.example.livingai.utils import android.content.Context import android.graphics.Bitmap import android.graphics.BitmapFactory import android.graphics.Canvas import android.graphics.Color import android.graphics.Paint import androidx.annotation.DrawableRes import androidx.core.graphics.createBitmap import java.util.concurrent.ConcurrentHashMap object SilhouetteManager { private val originals = ConcurrentHashMap() private val inverted = ConcurrentHashMap() private val bitmasks = ConcurrentHashMap() fun initialize(context: Context, names: List) { names.forEach { name -> val resId = context.resources.getIdentifier(name, "drawable", context.packageName) if (resId != 0) { val bmp = BitmapFactory.decodeResource(context.resources, resId) originals[name] = bmp val inv = invertBitmap(bmp) inverted[name] = inv bitmasks[name] = createBitmask(inv) } } } fun getOriginal(name: String): Bitmap? = originals[name] fun getInverted(name: String): Bitmap? = inverted[name] fun getBitmask(name: String): BooleanArray? = bitmasks[name] private fun invertBitmap(src: Bitmap): Bitmap { val bmOut = Bitmap.createBitmap(src.width, src.height, src.config ?: Bitmap.Config.ARGB_8888) val canvas = Canvas(bmOut) val paint = Paint() val colorMatrix = android.graphics.ColorMatrix( floatArrayOf( -1f, 0f, 0f, 0f, 255f, 0f, -1f, 0f, 0f, 255f, 0f, 0f, -1f, 0f, 255f, 0f, 0f, 0f, 1f, 0f ) ) paint.colorFilter = android.graphics.ColorMatrixColorFilter(colorMatrix) canvas.drawBitmap(src, 0f, 0f, paint) return bmOut } private fun createBitmask(bitmap: Bitmap): BooleanArray { val w = bitmap.width val h = bitmap.height val mask = BooleanArray(w * h) val pixels = IntArray(w * h) bitmap.getPixels(pixels, 0, w, 0, 0, w, h) for (i in pixels.indices) { val c = pixels[i] val alpha = Color.alpha(c) // simple threshold: non-transparent and not near-white (assuming inverted is black on transparent/white) // The inverted logic makes black -> white, white -> black. // Wait, if original is black silhouette on transparent: // Inverted: black becomes white, transparent becomes... white? // Let's check invertBitmap logic. // Matrix: R' = 255 - R, G' = 255 - G, B' = 255 - B, A' = A. // If original is Black (0,0,0,255) -> White (255,255,255,255). // If original is Transparent (0,0,0,0) -> Transparent (0,0,0,0). // So "Inverted" means we have White silhouette on Transparent. // We want bitmask where the silhouette is. // So we look for non-transparent pixels. mask[i] = alpha > 16 } return mask } }