@@ -20,7 +20,6 @@ import co.stonephone.stonecamera.StoneCameraViewModel
2020import co.stonephone.stonecamera.utils.ImageSegmenterHelper
2121import com.google.mediapipe.framework.image.BitmapImageBuilder
2222import com.google.mediapipe.framework.image.ByteBufferExtractor
23- import com.google.mediapipe.tasks.vision.core.RunningMode
2423import com.google.mediapipe.tasks.vision.imagesegmenter.ImageSegmenterResult
2524import kotlinx.coroutines.CoroutineScope
2625import kotlinx.coroutines.Dispatchers
@@ -33,8 +32,7 @@ import java.util.Objects
3332import kotlin.math.max
3433import kotlin.math.min
3534
36-
37- class PortraitModePlugin : IPlugin , ImageSegmenterHelper .SegmenterListener {
35+ class PortraitModePlugin : IPlugin {
3836 override val id: String = " portraitModePlugin"
3937 override val name: String = " Portrait Mode"
4038
@@ -45,10 +43,8 @@ class PortraitModePlugin : IPlugin, ImageSegmenterHelper.SegmenterListener {
4543 override fun initialize (viewModel : StoneCameraViewModel ) {
4644 imageSegmenterHelper = ImageSegmenterHelper (
4745 context = MyApplication .getAppContext(),
48- runningMode = RunningMode .IMAGE ,
4946 currentModel = ImageSegmenterHelper .MODEL_SELFIE_SEGMENTER ,
5047 currentDelegate = ImageSegmenterHelper .DELEGATE_CPU ,
51- imageSegmenterListener = this
5248 )
5349
5450 imageSegmenterHelper.setupImageSegmenter()
@@ -77,7 +73,7 @@ class PortraitModePlugin : IPlugin, ImageSegmenterHelper.SegmenterListener {
7773 imageSegmenterHelper.segmentImageFile(BitmapImageBuilder (bitmap).build())
7874 ? : return @launch
7975
80- // Blur mask edge with https://developer.android.com/reference/android/graphics/BlurMaskFilter
76+ // TODO Blur mask edge with https://developer.android.com/reference/android/graphics/BlurMaskFilter
8177 val categoryMask: ByteBuffer =
8278 ByteBufferExtractor .extract(segmentationResults.categoryMask().get())
8379
@@ -89,9 +85,20 @@ class PortraitModePlugin : IPlugin, ImageSegmenterHelper.SegmenterListener {
8985 }
9086 }
9187
88+ private fun applyBlurBasedOnMask (context : Context , imageUri : Uri , categoryMask : ByteBuffer ): Bitmap ? {
89+ // Step 1: Load the image from URI
90+ val capturedImage = loadBitmapFromUri(context, imageUri) ? : return null
91+
92+ categoryMask.rewind() // Reset ByteBuffer position
93+
94+ val blurredBitmap = fastBlur(capturedImage, categoryMask, 25 )
95+
96+ return blurredBitmap
97+ }
98+
9299 // Stolen from https://stackoverflow.com/questions/21418892/understanding-super-fast-blur-algorithm?fbclid=IwZXh0bgNhZW0CMTEAAR1w91ucNtw4nU-Z8Z9RyMYFVUHWxfgt7ivsE7foTkwR2wmdx2losQqQ0sk_aem_Zrf_8344PRxW6SFzutkE7g
93100 // Edited to apply the blur only on the mask
94- fun fastBlur (original : Bitmap , mask : ByteBuffer , radius : Int ): Bitmap {
101+ private fun fastBlur (original : Bitmap , mask : ByteBuffer , radius : Int ): Bitmap {
95102 if (radius < 1 ) {
96103 return original
97104 }
@@ -221,18 +228,7 @@ class PortraitModePlugin : IPlugin, ImageSegmenterHelper.SegmenterListener {
221228 return img
222229 }
223230
224- fun applyBlurBasedOnMask (context : Context , imageUri : Uri , categoryMask : ByteBuffer ): Bitmap ? {
225- // Step 1: Load the image from URI
226- val capturedImage = loadBitmapFromUri(context, imageUri) ? : return null
227-
228- categoryMask.rewind() // Reset ByteBuffer position
229-
230- val blurredBitmap = fastBlur(capturedImage, categoryMask, 25 )
231-
232- return blurredBitmap
233- }
234-
235- fun loadBitmapFromUri (context : Context , uri : Uri ): Bitmap ? {
231+ private fun loadBitmapFromUri (context : Context , uri : Uri ): Bitmap ? {
236232 try {
237233 val inputStream = context.contentResolver.openInputStream(uri)
238234 return BitmapFactory .decodeStream(inputStream)
@@ -242,7 +238,7 @@ class PortraitModePlugin : IPlugin, ImageSegmenterHelper.SegmenterListener {
242238 }
243239 }
244240
245- fun Bitmap.saveImage (context : Context ): Uri ? {
241+ private fun Bitmap.saveImage (context : Context ): Uri ? {
246242 if (android.os.Build .VERSION .SDK_INT >= 29 ) {
247243 val values = ContentValues ()
248244 values.put(MediaStore .Images .Media .MIME_TYPE , " image/jpeg" )
@@ -281,7 +277,7 @@ class PortraitModePlugin : IPlugin, ImageSegmenterHelper.SegmenterListener {
281277 return null
282278 }
283279
284- fun saveImageToStream (bitmap : Bitmap , outputStream : OutputStream ? ) {
280+ private fun saveImageToStream (bitmap : Bitmap , outputStream : OutputStream ? ) {
285281 if (outputStream != null ) {
286282 try {
287283 bitmap.compress(Bitmap .CompressFormat .JPEG , 100 , outputStream)
@@ -323,12 +319,4 @@ class PortraitModePlugin : IPlugin, ImageSegmenterHelper.SegmenterListener {
323319 renderLocation = SettingLocation .TOP
324320 )
325321 )
326-
327- override fun onError (error : String , errorCode : Int ) {
328- TODO (" Not yet implemented" )
329- }
330-
331- override fun onResults (resultBundle : ImageSegmenterHelper .ResultBundle ) {
332- TODO (" Not yet implemented" )
333- }
334322}
0 commit comments