diff --git a/feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/MlKitSubjectBackgroundRemover.kt b/feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidAutoBackgroundRemoverBackend.kt similarity index 57% rename from feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/MlKitSubjectBackgroundRemover.kt rename to feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidAutoBackgroundRemoverBackend.kt index 79c88e422..c8c22b22d 100644 --- a/feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/MlKitSubjectBackgroundRemover.kt +++ b/feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidAutoBackgroundRemoverBackend.kt @@ -1,6 +1,6 @@ /* * ImageToolbox is an image editor for android - * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov) + * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov) * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,21 +18,19 @@ package ru.tech.imageresizershrinker.feature.erase_background.data import android.graphics.Bitmap -import android.os.Build -import androidx.annotation.RequiresApi +import ru.tech.imageresizershrinker.feature.erase_background.domain.AutoBackgroundRemoverBackend +import javax.inject.Inject -@RequiresApi(api = Build.VERSION_CODES.N) -internal object MlKitSubjectBackgroundRemover { +internal class AndroidAutoBackgroundRemoverBackend @Inject constructor() : + AutoBackgroundRemoverBackend { - /** - * Process the image to get buffer and image height and width - * @param bitmap Bitmap which you want to remove background. - * @param onFinish listener for success and failure callback. - **/ - @RequiresApi(api = Build.VERSION_CODES.N) - fun removeBackground( - bitmap: Bitmap, + override fun performBackgroundRemove( + image: Bitmap, onFinish: (Result) -> Unit - ) = onFinish(Result.failure(UnsupportedOperationException("FOSS"))) + ) { + onFinish( + Result.failure(UnsupportedOperationException("FOSS")) + ) + } } \ No newline at end of file diff --git a/feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/MlKitBackgroundRemover.kt b/feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/MlKitBackgroundRemover.kt deleted file mode 100644 index 532d235a2..000000000 --- a/feature/erase-background/src/foss/java/ru/tech/imageresizershrinker/feature/erase_background/data/MlKitBackgroundRemover.kt +++ /dev/null @@ -1,41 +0,0 @@ -/* - * ImageToolbox is an image editor for android - * Copyright (c) 2024 T8RIN (Malik Mukhametzyanov) - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - * - * You should have received a copy of the Apache License - * along with this program. If not, see . - */ - -package ru.tech.imageresizershrinker.feature.erase_background.data - -import android.graphics.Bitmap -import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.launch - -internal object MlKitBackgroundRemover { - - /** - * Process the image to get buffer and image height and width - * @param bitmap Bitmap which you want to remove background. - * @param onFinish listener for success and failure callback. - **/ - fun removeBackground( - bitmap: Bitmap, - scope: CoroutineScope, - onFinish: suspend (Result) -> Unit - ) { - scope.launch { - onFinish(Result.failure(UnsupportedOperationException("FOSS"))) - } - } - -} \ No newline at end of file diff --git a/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidAutoBackgroundRemover.kt b/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidAutoBackgroundRemover.kt index 7585fcd66..157b18c21 100644 --- a/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidAutoBackgroundRemover.kt +++ b/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidAutoBackgroundRemover.kt @@ -17,21 +17,19 @@ package ru.tech.imageresizershrinker.feature.erase_background.data -import android.annotation.SuppressLint import android.graphics.Bitmap -import android.os.Build import androidx.compose.ui.graphics.Color import androidx.compose.ui.graphics.toArgb -import kotlinx.coroutines.CoroutineScope +import com.t8rin.logger.makeLog import kotlinx.coroutines.async import kotlinx.coroutines.coroutineScope -import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder import ru.tech.imageresizershrinker.feature.erase_background.domain.AutoBackgroundRemover +import ru.tech.imageresizershrinker.feature.erase_background.domain.AutoBackgroundRemoverBackend import javax.inject.Inject internal class AndroidAutoBackgroundRemover @Inject constructor( - dispatchersHolder: DispatchersHolder -) : DispatchersHolder by dispatchersHolder, AutoBackgroundRemover { + private val backend: AutoBackgroundRemoverBackend +) : AutoBackgroundRemover { override suspend fun trimEmptyParts( image: Bitmap @@ -83,54 +81,16 @@ internal class AndroidAutoBackgroundRemover @Inject constructor( image: Bitmap, onSuccess: (Bitmap) -> Unit, onFailure: (Throwable) -> Unit - ) { - runCatching { - autoRemove( - type = ApiType.Best, - image = image, - onFinish = { - it.onSuccess(onSuccess).onFailure(onFailure) + ) = backend.performBackgroundRemove( + image = image, + onFinish = { result -> + result + .onSuccess(onSuccess) + .onFailure { + it.makeLog() + onFailure(it) } - ) - }.onFailure(onFailure) - } - - private fun autoRemove( - type: ApiType, - image: Bitmap, - onFinish: (Result) -> Unit - ) { - val old = { - MlKitBackgroundRemover.removeBackground( - bitmap = image, - scope = CoroutineScope(defaultDispatcher), - onFinish = onFinish - ) } - val new = { - @SuppressLint("NewApi") - MlKitSubjectBackgroundRemover.removeBackground( - bitmap = image, - onFinish = { - if (it.isFailure) { - old() - } else onFinish(it) - } - ) - } - - when (type) { - ApiType.Old -> old() - ApiType.New -> new() - } - } - - private enum class ApiType { - Old, New; - - companion object { - val Best: ApiType get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) New else Old - } - } + ) } \ No newline at end of file diff --git a/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/di/EraseBackgroundModule.kt b/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/di/EraseBackgroundModule.kt index 2850b7343..04bd9f84a 100644 --- a/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/di/EraseBackgroundModule.kt +++ b/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/di/EraseBackgroundModule.kt @@ -23,7 +23,9 @@ import dagger.Module import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import ru.tech.imageresizershrinker.feature.erase_background.data.AndroidAutoBackgroundRemover +import ru.tech.imageresizershrinker.feature.erase_background.data.AndroidAutoBackgroundRemoverBackend import ru.tech.imageresizershrinker.feature.erase_background.domain.AutoBackgroundRemover +import ru.tech.imageresizershrinker.feature.erase_background.domain.AutoBackgroundRemoverBackend import javax.inject.Singleton @Module @@ -36,4 +38,10 @@ internal interface EraseBackgroundModule { remover: AndroidAutoBackgroundRemover ): AutoBackgroundRemover + @Binds + @Singleton + fun provideBackend( + backend: AndroidAutoBackgroundRemoverBackend + ): AutoBackgroundRemoverBackend + } \ No newline at end of file diff --git a/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/domain/AutoBackgroundRemoverBackend.kt b/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/domain/AutoBackgroundRemoverBackend.kt new file mode 100644 index 000000000..efa44118c --- /dev/null +++ b/feature/erase-background/src/main/java/ru/tech/imageresizershrinker/feature/erase_background/domain/AutoBackgroundRemoverBackend.kt @@ -0,0 +1,27 @@ +/* + * ImageToolbox is an image editor for android + * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * You should have received a copy of the Apache License + * along with this program. If not, see . + */ + +package ru.tech.imageresizershrinker.feature.erase_background.domain + +internal interface AutoBackgroundRemoverBackend { + + fun performBackgroundRemove( + image: I, + onFinish: (Result) -> Unit + ) + +} \ No newline at end of file diff --git a/feature/erase-background/src/market/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidBackgroundRemoverBackend.kt b/feature/erase-background/src/market/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidBackgroundRemoverBackend.kt new file mode 100644 index 000000000..e30376773 --- /dev/null +++ b/feature/erase-background/src/market/java/ru/tech/imageresizershrinker/feature/erase_background/data/AndroidBackgroundRemoverBackend.kt @@ -0,0 +1,84 @@ +/* + * ImageToolbox is an image editor for android + * Copyright (c) 2025 T8RIN (Malik Mukhametzyanov) + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + * You should have received a copy of the Apache License + * along with this program. If not, see . + */ + +package ru.tech.imageresizershrinker.feature.erase_background.data + +import android.annotation.SuppressLint +import android.graphics.Bitmap +import android.os.Build +import kotlinx.coroutines.CoroutineScope +import ru.tech.imageresizershrinker.core.domain.dispatchers.DispatchersHolder +import ru.tech.imageresizershrinker.feature.erase_background.domain.AutoBackgroundRemoverBackend +import javax.inject.Inject + +internal class AndroidAutoBackgroundRemoverBackend @Inject constructor( + dispatchersHolder: DispatchersHolder +) : AutoBackgroundRemoverBackend, DispatchersHolder by dispatchersHolder { + + override fun performBackgroundRemove( + image: Bitmap, + onFinish: (Result) -> Unit + ) { + runCatching { + autoRemove( + image = image, + onFinish = onFinish + ) + }.onFailure { + onFinish(Result.failure(it)) + } + } + + @SuppressLint("NewApi") + private fun autoRemove( + type: ApiType = ApiType.Best, + image: Bitmap, + onFinish: (Result) -> Unit + ) { + val old = { + MlKitBackgroundRemover.removeBackground( + bitmap = image, + scope = CoroutineScope(defaultDispatcher), + onFinish = onFinish + ) + } + val new = { + MlKitSubjectBackgroundRemover.removeBackground( + bitmap = image, + onFinish = { + if (it.isFailure) { + old() + } else onFinish(it) + } + ) + } + + when (type) { + ApiType.Old -> old() + ApiType.New -> new() + } + } + + private enum class ApiType { + Old, New; + + companion object { + val Best: ApiType get() = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) New else Old + } + } + +} \ No newline at end of file