PixelDroid-App-Android/mediaEditor/src/main/java/org/pixeldroid/media_editor/photoEdit/cropper/CropImageView.kt

105 lines
4.0 KiB
Kotlin
Raw Normal View History

2022-10-28 20:49:25 +02:00
package org.pixeldroid.media_editor.photoEdit.cropper
2022-10-17 13:23:02 +02:00
2022-10-21 17:11:37 +02:00
// Simplified version of https://github.com/ArthurHub/Android-Image-Cropper , which is
// licensed under the Apache License, Version 2.0. The modifications made to it for PixelDroid
// are under licensed under the GPLv3 or later, just like the rest of the PixelDroid project
2022-10-17 13:23:02 +02:00
import android.content.Context
import android.graphics.Rect
import android.graphics.RectF
import android.graphics.drawable.Drawable
import android.net.Uri
import android.util.AttributeSet
import android.view.LayoutInflater
import android.widget.FrameLayout
import androidx.core.graphics.toRect
import com.bumptech.glide.Glide
import com.bumptech.glide.load.DataSource
import com.bumptech.glide.load.engine.GlideException
import com.bumptech.glide.request.RequestListener
import com.bumptech.glide.request.target.Target
2022-10-28 20:49:25 +02:00
import org.pixeldroid.media_editor.databinding.CropImageViewBinding
import org.pixeldroid.media_editor.photoEdit.VideoEditActivity
2022-10-17 13:23:02 +02:00
/** Custom view that provides cropping capabilities to an image. */
class CropImageView @JvmOverloads constructor(context: Context?, attrs: AttributeSet? = null) :
FrameLayout(context!!, attrs) {
2022-10-19 00:19:42 +02:00
private val binding: CropImageViewBinding =
CropImageViewBinding.inflate(LayoutInflater.from(context), this, true)
2022-10-17 13:23:02 +02:00
init {
2022-10-19 00:19:42 +02:00
binding.CropOverlayView.setInitialAttributeValues()
2022-10-17 13:23:02 +02:00
}
/**
* Gets the crop window's position relative to the parent's view at screen.
*
2022-10-19 00:19:42 +02:00
* @return a Rect instance containing notCropped area boundaries of the source Bitmap
2022-10-17 13:23:02 +02:00
*/
2022-10-21 17:11:37 +02:00
val cropWindowRect: RectF
2022-10-19 00:19:42 +02:00
get() = binding.CropOverlayView.cropWindowRect
2022-10-17 13:23:02 +02:00
/** Reset crop window to initial rectangle. */
fun resetCropRect() {
2022-10-19 00:19:42 +02:00
binding.CropOverlayView.resetCropWindowRect()
2022-10-17 13:23:02 +02:00
}
2022-10-19 00:19:42 +02:00
fun getInitialCropWindowRect(): Rect = binding.CropOverlayView.initialCropWindowRect
2022-10-17 13:23:02 +02:00
/**
2022-10-19 00:19:42 +02:00
* Sets the image loaded from the given URI as the content of the CropImageView
2022-10-17 13:23:02 +02:00
*
* @param uri the URI to load the image from
*/
2022-10-19 00:19:42 +02:00
fun setImageUriAsync(uri: Uri, cropRelativeDimensions: VideoEditActivity.RelativeCropPosition) {
// either no existing task is working or we canceled it, need to load new URI
2022-10-21 17:11:37 +02:00
binding.CropOverlayView.initialCropWindowRect = Rect()
2022-10-17 13:23:02 +02:00
Glide.with(this).load(uri).fitCenter().listener(object : RequestListener<Drawable> {
2022-10-19 00:19:42 +02:00
override fun onLoadFailed(
e: GlideException?,
m: Any?,
t: Target<Drawable>?,
i: Boolean,
): Boolean {
return false
}
2022-10-17 13:23:02 +02:00
override fun onResourceReady(
resource: Drawable?,
model: Any?,
target: Target<Drawable>?,
dataSource: DataSource?,
2022-10-19 00:19:42 +02:00
isFirstResource: Boolean,
2022-10-17 13:23:02 +02:00
): Boolean {
// Get width and height that the image will take on the screen
val drawnWidth = resource?.intrinsicWidth ?: width
val drawnHeight = resource?.intrinsicHeight ?: height
2022-10-19 00:19:42 +02:00
binding.CropOverlayView.initialCropWindowRect = RectF(
(width - drawnWidth) / 2f,
(height - drawnHeight) / 2f,
(width + drawnWidth) / 2f,
(height + drawnHeight) / 2f
).toRect()
binding.CropOverlayView.setCropWindowLimits(
drawnWidth.toFloat(),
drawnHeight.toFloat()
)
binding.CropOverlayView.invalidate()
binding.CropOverlayView.setBounds(width, height)
binding.CropOverlayView.resetCropOverlayView()
if (!cropRelativeDimensions.notCropped()) binding.CropOverlayView.setRecordedCropWindowRect(cropRelativeDimensions)
binding.CropOverlayView.visibility = VISIBLE
2022-10-17 13:23:02 +02:00
// Indicate to Glide that the image hasn't been set yet
return false
}
2022-10-19 00:19:42 +02:00
}).into(binding.ImageViewImage)
2022-10-17 13:23:02 +02:00
}
}