From 6e5802f0212b82c0f901b0eec31274363c68aa89 Mon Sep 17 00:00:00 2001 From: terofeev Date: Fri, 7 Feb 2025 18:24:10 +0400 Subject: [PATCH 1/2] Implement internal cropping instead of library's built-in function --- .../gallery/activities/EditActivity.kt | 38 ++++++++++++++++--- 1 file changed, 33 insertions(+), 5 deletions(-) diff --git a/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt b/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt index 21bff6bc8..16cf5abf4 100644 --- a/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt +++ b/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt @@ -10,9 +10,12 @@ import android.net.Uri import android.os.Bundle import android.os.Handler import android.provider.MediaStore +import android.view.View import android.widget.ImageView import android.widget.RelativeLayout +import androidx.core.view.isInvisible import androidx.exifinterface.media.ExifInterface +import androidx.lifecycle.lifecycleScope import androidx.recyclerview.widget.LinearLayoutManager import com.bumptech.glide.Glide import com.bumptech.glide.load.DataSource @@ -25,6 +28,7 @@ import com.bumptech.glide.request.target.Target import com.canhub.cropper.CropImageView import com.zomato.photofilters.FilterPack import com.zomato.photofilters.imageprocessors.Filter +import kotlinx.coroutines.* import org.fossify.commons.dialogs.ColorPickerDialog import org.fossify.commons.extensions.* import org.fossify.commons.helpers.NavigationIcon @@ -87,6 +91,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener private var oldExif: ExifInterface? = null private var filterInitialBitmap: Bitmap? = null private var originalUri: Uri? = null + private var bitmapCroppingJob: Job? = null private val binding by viewBinding(ActivityEditBinding::inflate) override fun onCreate(savedInstanceState: Bundle?) { @@ -313,7 +318,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener setOldExif() if (binding.cropImageView.isVisible()) { - binding.cropImageView.croppedImageAsync() + cropImageAsync() } else if (binding.editorDrawCanvas.isVisible()) { val bitmap = binding.editorDrawCanvas.getBitmap() if (saveUri.scheme == "file") { @@ -351,6 +356,26 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener } } + private fun setCropProgressBarVisibility(visible: Boolean) { + val progressBar: View? = binding.cropImageView.findViewById(com.canhub.cropper.R.id.CropProgressBar) + progressBar?.isInvisible = visible.not() + } + + private fun cropImageAsync() { + setCropProgressBarVisibility(visible = true) + bitmapCroppingJob?.cancel() + bitmapCroppingJob = lifecycleScope.launch(CoroutineExceptionHandler { _, t -> + onCropImageComplete(bitmap = null, error = Exception(t)) + }) { + val bitmap = withContext(Dispatchers.Default) { + binding.cropImageView.getCroppedImage() + } + onCropImageComplete(bitmap, null) + }.apply { + invokeOnCompletion { setCropProgressBarVisibility(visible = false) } + } + } + private fun setOldExif() { var inputStream: InputStream? = null try { @@ -764,7 +789,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener ResizeDialog(this, point) { resizeWidth = it.x resizeHeight = it.y - binding.cropImageView.croppedImageAsync() + cropImageAsync() } } @@ -793,10 +818,13 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener } override fun onCropImageComplete(view: CropImageView, result: CropImageView.CropResult) { - if (result.error == null && result.bitmap != null) { + onCropImageComplete(result.bitmap, result.error) + } + + private fun onCropImageComplete(bitmap: Bitmap?, error: Exception?) { + if (error == null && bitmap != null) { setOldExif() - val bitmap = result.bitmap!! if (isSharingBitmap) { isSharingBitmap = false shareBitmap(bitmap) @@ -843,7 +871,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener toast(R.string.unknown_file_location) } } else { - toast("${getString(R.string.image_editing_failed)}: ${result.error?.message}") + toast("${getString(R.string.image_editing_failed)}: ${error?.message}") } } From f196e111c779f58cce3ac6de9e372a0fbe7e9e5c Mon Sep 17 00:00:00 2001 From: terofeev Date: Sat, 8 Feb 2025 13:36:58 +0400 Subject: [PATCH 2/2] Apply internal cropping when sharing an image --- .../org/fossify/gallery/activities/EditActivity.kt | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt b/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt index 16cf5abf4..39a4603d9 100644 --- a/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt +++ b/app/src/main/kotlin/org/fossify/gallery/activities/EditActivity.kt @@ -51,7 +51,7 @@ import org.fossify.gallery.models.FilterItem import java.io.* import kotlin.math.max -class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener { +class EditActivity : SimpleActivity() { companion object { init { System.loadLibrary("NativeImageProcessor") @@ -256,7 +256,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener binding.editorDrawCanvas.beGone() binding.cropImageView.apply { beVisible() - setOnCropImageCompleteListener(this@EditActivity) setImageUriAsync(uri) guidelines = CropImageView.Guidelines.ON @@ -405,7 +404,7 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener binding.cropImageView.isVisible() -> { isSharingBitmap = true runOnUiThread { - binding.cropImageView.croppedImageAsync() + cropImageAsync() } } @@ -817,10 +816,6 @@ class EditActivity : SimpleActivity(), CropImageView.OnCropImageCompleteListener } } - override fun onCropImageComplete(view: CropImageView, result: CropImageView.CropResult) { - onCropImageComplete(result.bitmap, result.error) - } - private fun onCropImageComplete(bitmap: Bitmap?, error: Exception?) { if (error == null && bitmap != null) { setOldExif()