@ -380,6 +380,9 @@ class ScreenCaptureService : Service() {
}
private fun processImage ( image : Image ) {
var bitmap : Bitmap ? = null
var croppedBitmap : Bitmap ? = null
try {
val planes = image . planes
val buffer = planes [ 0 ] . buffer
@ -391,7 +394,7 @@ class ScreenCaptureService : Service() {
Log . d ( TAG , " 🖼️ CAPTURE DEBUG: screenSize= ${screenWidth} x ${screenHeight} , expected bitmap= ${screenWidth + rowPadding / pixelStride} x ${screenHeight} " )
// Create bitmap from image
val bitmap = Bitmap . createBitmap (
bitmap = Bitmap . createBitmap (
screenWidth + rowPadding / pixelStride ,
screenHeight ,
Bitmap . Config . ARGB_8888
@ -401,7 +404,7 @@ class ScreenCaptureService : Service() {
Log . d ( TAG , " 🖼️ CAPTURE DEBUG: created bitmap= ${bitmap.width} x ${bitmap.height} " )
// Convert to cropped bitmap if needed
val croppedBitmap = if ( rowPadding == 0 ) {
croppedBitmap = if ( rowPadding == 0 ) {
Log . d ( TAG , " 🖼️ CAPTURE DEBUG: No padding, using original bitmap " )
bitmap
} else {
@ -437,14 +440,14 @@ class ScreenCaptureService : Service() {
analyzePokemonScreen ( mat )
}
// Clean up
if ( croppedBitmap != bitmap ) {
croppedBitmap . recycle ( )
}
bitmap . recycle ( )
} catch ( e : Exception ) {
Log . e ( TAG , " Error processing image " , e )
} finally {
// Always clean up bitmaps in finally block to prevent leaks
if ( croppedBitmap != null && croppedBitmap != bitmap ) {
croppedBitmap . recycle ( )
}
bitmap ?. recycle ( )
}
}
@ -747,12 +750,16 @@ class ScreenCaptureService : Service() {
Utils . matToBitmap ( processedRoi , bitmap )
// Use ML Kit OCR
val extractedText = performOCR ( bitmap , detection . className )
val extractedText = try {
performOCR ( bitmap , detection . className )
} finally {
// Always clean up bitmap after OCR
bitmap . recycle ( )
}
// Clean up
roi . release ( )
processedRoi . release ( )
bitmap . recycle ( )
if ( extractedText != null ) {
Log . i ( TAG , " ✅ YOLO SUCCESS: ${detection.className} = ' $extractedText ' (conf: ${String.format("%.2f", detection.confidence)} ) " )
@ -1149,6 +1156,10 @@ class ScreenCaptureService : Service() {
}
private fun convertImageToMat ( image : Image ) : Mat ? {
var bitmap : Bitmap ? = null
var croppedBitmap : Bitmap ? = null
var mat : Mat ? = null
return try {
val planes = image . planes
val buffer = planes [ 0 ] . buffer
@ -1157,7 +1168,7 @@ class ScreenCaptureService : Service() {
val rowPadding = rowStride - pixelStride * screenWidth
// Create bitmap from image
val bitmap = Bitmap . createBitmap (
bitmap = Bitmap . createBitmap (
screenWidth + rowPadding / pixelStride ,
screenHeight ,
Bitmap . Config . ARGB_8888
@ -1165,29 +1176,36 @@ class ScreenCaptureService : Service() {
bitmap . copyPixelsFromBuffer ( buffer )
// Crop bitmap to remove padding if needed
val croppedBitmap = if ( rowPadding == 0 ) {
croppedBitmap = if ( rowPadding == 0 ) {
bitmap
} else {
val cropped = Bitmap . createBitmap ( bitmap , 0 , 0 , screenWidth , screenHeight )
bitmap . recycle ( ) // Clean up original
bitmap = null // Mark as recycled
cropped
}
// Convert bitmap to Mat
val mat = Mat ( )
mat = Mat ( )
Utils . bitmapToMat ( croppedBitmap , mat )
// Convert from RGBA to BGR (OpenCV format for proper color channel handling)
val bgrMat = Mat ( )
Imgproc . cvtColor ( mat , bgrMat , Imgproc . COLOR_RGBA2BGR )
// Clean up
// Clean up intermediate resources
mat . release ( )
croppedBitmap . recycle ( )
bgrMat
} catch ( e : Exception ) {
Log . e ( TAG , " ❌ Error converting image to Mat " , e )
// Clean up on error
mat ?. release ( )
if ( croppedBitmap != null && croppedBitmap != bitmap ) {
croppedBitmap . recycle ( )
}
bitmap ?. recycle ( )
null
}
}