@@ -4,7 +4,6 @@ import android.content.Context
44import android.graphics.Bitmap
55import android.graphics.BitmapFactory
66import android.net.Uri
7- import androidx.core.content.ContextCompat
87import io.github.ismoy.imagepickerkmp.data.camera.CameraController.CameraType
98import io.github.ismoy.imagepickerkmp.domain.exceptions.ImageProcessingException
109import io.github.ismoy.imagepickerkmp.domain.models.CompressionLevel
@@ -13,17 +12,18 @@ import io.github.ismoy.imagepickerkmp.domain.config.HighPerformanceConfig
1312import io.github.ismoy.imagepickerkmp.domain.utils.ExifDataExtractor
1413import kotlinx.coroutines.CoroutineScope
1514import kotlinx.coroutines.Dispatchers
15+ import kotlinx.coroutines.SupervisorJob
1616import kotlinx.coroutines.launch
1717import kotlinx.coroutines.withContext
1818import java.io.File
19- import java.io.FileOutputStream
2019import androidx.core.graphics.scale
2120
2221
2322internal class ImageProcessor (
2423 private val context : Context ,
2524 private val fileManager : io.github.ismoy.imagepickerkmp.data.managers.FileManager ,
26- private val orientationCorrector : ImageOrientationCorrector
25+ private val orientationCorrector : ImageOrientationCorrector ,
26+ private val processingScope : CoroutineScope = CoroutineScope (Dispatchers .Default + SupervisorJob ())
2727) {
2828
2929 fun processImage (
@@ -34,7 +34,7 @@ internal class ImageProcessor(
3434 onPhotoCaptured : (PhotoResult ) -> Unit ,
3535 onError : (Exception ) -> Unit
3636 ) {
37- CoroutineScope ( Dispatchers . Default ) .launch {
37+ processingScope .launch {
3838 try {
3939 val exifData = if (includeExif) {
4040 try {
@@ -51,7 +51,7 @@ internal class ImageProcessor(
5151 val correctedImageFile = orientationCorrector.correctImageOrientation(imageFile, cameraType)
5252
5353 val options = BitmapFactory .Options ().apply {
54- inPreferredConfig = if (HighPerformanceConfig .isHighEndDevice()) {
54+ inPreferredConfig = if (HighPerformanceConfig .isHighEndDevice(context )) {
5555 Bitmap .Config .ARGB_8888
5656 } else {
5757 Bitmap .Config .RGB_565
@@ -61,9 +61,16 @@ internal class ImageProcessor(
6161 }
6262
6363 val originalBitmap = BitmapFactory .decodeFile(correctedImageFile.absolutePath, options)
64+ ? : run {
65+ withContext(Dispatchers .Main ) {
66+ onError(ImageProcessingException (" Failed to decode captured image." ))
67+ }
68+ return @launch
69+ }
6470
65- if (originalBitmap != null ) {
66- val processedBitmap = if (compressionLevel != null ) {
71+ var processedBitmap: Bitmap ? = null
72+ try {
73+ processedBitmap = if (compressionLevel != null ) {
6774 processImageWithCompression(originalBitmap, compressionLevel)
6875 } else {
6976 originalBitmap
@@ -88,14 +95,23 @@ internal class ImageProcessor(
8895 originalBitmap.recycle()
8996 }
9097 processedBitmap.recycle()
98+ processedBitmap = null
99+ if (compressionLevel != null && finalFile != correctedImageFile) {
100+ correctedImageFile.delete()
101+ }
102+ if (correctedImageFile != imageFile) {
103+ imageFile.delete()
104+ }
91105
92106 withContext(Dispatchers .Main ) {
93107 onPhotoCaptured(result)
94108 }
95- } else {
96- withContext( Dispatchers . Main ) {
97- onError( ImageProcessingException ( " Failed to decode captured image. " ) )
109+ } catch (e : Exception ) {
110+ if (processedBitmap != null && processedBitmap != originalBitmap ) {
111+ processedBitmap.recycle( )
98112 }
113+ if (! originalBitmap.isRecycled) originalBitmap.recycle()
114+ throw e
99115 }
100116 } catch (e: Exception ) {
101117 withContext(Dispatchers .Main ) {
0 commit comments