Skip to content

Commit

Permalink
Blurring
Browse files Browse the repository at this point in the history
  • Loading branch information
shubertm committed Aug 3, 2023
1 parent f9e8248 commit 4b4059d
Show file tree
Hide file tree
Showing 10 changed files with 376 additions and 45 deletions.
2 changes: 2 additions & 0 deletions app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ dependencies {
implementation "ch.acra:acra-http:5.9.3"
implementation "ch.acra:acra-dialog:5.9.3"

implementation 'io.github.hokofly:hoko-blur:1.5.0'

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import androidx.compose.ui.graphics.graphicsLayer
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.input.pointer.pointerInteropFilter
import androidx.compose.ui.platform.LocalContext
import space.taran.arkretouch.presentation.edit.EditViewModel
import space.taran.arkretouch.presentation.picker.toDp
import kotlin.math.atan2
Expand Down Expand Up @@ -94,7 +95,10 @@ fun EditCanvas(viewModel: EditViewModel) {
}

@Composable
fun EditImageCanvas(modifier: Modifier, editManager: EditManager) {
fun EditImageCanvas(
modifier: Modifier,
editManager: EditManager
) {
Canvas(modifier) {
editManager.apply {
invalidatorTick.value
Expand All @@ -120,6 +124,7 @@ fun EditDrawCanvas(
viewModel: EditViewModel,
onRotate: (Int, Float, Float) -> Unit
) {
val context = LocalContext.current
val editManager = viewModel.editManager
var path = Path()
val currentPoint = PointF(0f, 0f)
Expand All @@ -134,7 +139,8 @@ fun EditDrawCanvas(
currentPoint.x = eventX
currentPoint.y = eventY
editManager.apply {
applyOperation(drawOperation.draw(path))
drawOperation.draw(path)
applyOperation()
}
}
MotionEvent.ACTION_MOVE -> {
Expand Down Expand Up @@ -194,6 +200,29 @@ fun EditDrawCanvas(
viewModel.applyEyeDropper(action, eventX.toInt(), eventY.toInt())
}

fun handleBlurEvent(action: Int, eventX: Float, eventY: Float) {
when (action) {
MotionEvent.ACTION_DOWN -> {
currentPoint.x = eventX
currentPoint.y = eventY
}
MotionEvent.ACTION_MOVE -> {
val position = Offset(
currentPoint.x,
currentPoint.y
)
val delta = Offset(
computeDeltaX(currentPoint.x, eventX),
computeDeltaY(currentPoint.y, eventY)
)
editManager.blurOperation.moveBrush(position, delta)
currentPoint.x = eventX
currentPoint.y = eventY
}
else -> {}
}
}

Canvas(
modifier = drawModifier
// Eraser leaves black line instead of erasing without this hack, it uses BlendMode.SrcOut
Expand All @@ -214,6 +243,11 @@ fun EditDrawCanvas(

when (true) {
editManager.isResizeMode.value -> {}
editManager.isBlurMode.value -> handleBlurEvent(
event.action,
eventX,
eventY
)
editManager.isCropMode.value -> handleCropEvent(
event.action,
eventX,
Expand Down Expand Up @@ -248,6 +282,10 @@ fun EditDrawCanvas(
if (isCropMode.value) matrix = Matrix()
canvas.nativeCanvas.setMatrix(matrix)
if (isResizeMode.value) return@drawIntoCanvas
if (isBlurMode.value) {
editManager.blurOperation.drawBrush(context, canvas)
return@drawIntoCanvas
}
if (isCropMode.value) {
editManager.cropWindow.show(canvas)
return@drawIntoCanvas
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import space.taran.arkretouch.data.ImageDefaults
import space.taran.arkretouch.data.Resolution
import space.taran.arkretouch.presentation.edit.ImageViewParams
import space.taran.arkretouch.presentation.edit.Operation
import space.taran.arkretouch.presentation.edit.blur.BlurOperation
import space.taran.arkretouch.presentation.edit.crop.CropOperation
import timber.log.Timber
import space.taran.arkretouch.presentation.edit.crop.CropWindow
Expand All @@ -41,26 +42,26 @@ class EditManager {
style = PaintingStyle.Stroke
blendMode = BlendMode.SrcOut
}
val blurIntensity = mutableStateOf(12f)

val cropWindow = CropWindow(this)

val drawOperation = DrawOperation(this)
val resizeOperation = ResizeOperation(this)
val rotateOperation = RotateOperation(this)
val cropOperation = CropOperation(this)
val blurOperation = BlurOperation(this)

private val currentPaint: Paint
get() = if (isEraseMode.value) {
erasePaint
} else {
drawPaint.value
get() = when (true) {
isEraseMode.value -> erasePaint
else -> drawPaint.value
}

val drawPaths = Stack<DrawPath>()
val redoPaths = Stack<DrawPath>()

val backgroundImage = mutableStateOf<ImageBitmap?>(null)
val _backgroundImage: State<ImageBitmap?> = backgroundImage
private val _backgroundColor = mutableStateOf(Color.Transparent)
val backgroundColor: State<Color> = _backgroundColor
private val backgroundImage2 = mutableStateOf<ImageBitmap?>(null)
Expand All @@ -84,7 +85,7 @@ class EditManager {
else
backgroundImage.value?.let {
IntSize(it.width, it.height)
} ?: resolution.value?.toIntSize()!!
} ?: resolution.value?.toIntSize() ?: drawAreaSize.value
}

private val _resolution = mutableStateOf<Resolution?>(null)
Expand Down Expand Up @@ -112,6 +113,9 @@ class EditManager {
private val _isEyeDropperMode = mutableStateOf(false)
val isEyeDropperMode = _isEyeDropperMode

private val _isBlurMode = mutableStateOf(false)
val isBlurMode = _isBlurMode

val rotationAngle = mutableStateOf(0F)
var prevRotationAngle = 0f

Expand All @@ -131,7 +135,15 @@ class EditManager {
val cropStack = Stack<ImageBitmap>()
val redoCropStack = Stack<ImageBitmap>()

fun applyOperation(operation: Operation) {
fun applyOperation() {
val operation: Operation =
when (true) {
isRotateMode.value -> rotateOperation
isCropMode.value -> cropOperation
isBlurMode.value -> blurOperation
isResizeMode.value -> resizeOperation
else -> drawOperation
}
operation.apply()
}

Expand Down Expand Up @@ -346,10 +358,17 @@ class EditManager {
updateRevised()
}

fun operationByTask(task: String) = when (task) {
fun addBlur() {
if (canRedo.value) clearRedo()
undoStack.add(BLUR)
updateRevised()
}

private fun operationByTask(task: String) = when (task) {
ROTATE -> rotateOperation
RESIZE -> resizeOperation
CROP -> cropOperation
BLUR -> blurOperation
else -> drawOperation
}

Expand Down Expand Up @@ -434,6 +453,7 @@ class EditManager {
clearResizes()
clearRotations()
clearCrop()
blurOperation.clear()
undoStack.clear()
redoStack.clear()
restoreOriginalBackgroundImage()
Expand Down Expand Up @@ -502,6 +522,9 @@ class EditManager {
editMatrix.reset()
}

fun toggleBlurMode() {
_isBlurMode.value = !isBlurMode.value
}
fun setPaintStrokeWidth(strokeWidth: Float) {
drawPaint.value.strokeWidth = strokeWidth
}
Expand All @@ -522,6 +545,7 @@ class EditManager {
private const val CROP = "crop"
private const val RESIZE = "resize"
private const val ROTATE = "rotate"
private const val BLUR = "blur"
}
}

Expand All @@ -546,6 +570,9 @@ fun Paint.copy(): Paint {
shader = from.shader
colorFilter = from.colorFilter
pathEffect = from.pathEffect
asFrameworkPaint().apply {
maskFilter = from.asFrameworkPaint().maskFilter
}
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package space.taran.arkretouch.presentation.edit

import android.widget.Toast
import androidx.compose.animation.AnimatedVisibility
import androidx.compose.animation.core.tween
import androidx.compose.animation.fadeIn
Expand Down Expand Up @@ -39,7 +40,9 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.draw.clip
import androidx.compose.ui.graphics.Color
import androidx.compose.ui.graphics.toArgb
import androidx.compose.ui.graphics.vector.ImageVector
import androidx.compose.ui.platform.LocalContext
import androidx.compose.ui.res.vectorResource
import androidx.compose.ui.unit.dp
import androidx.compose.ui.unit.sp
Expand All @@ -61,12 +64,19 @@ fun ColorPickerDialog(
) {
if (!isVisible.value) return

val context = LocalContext.current

var currentColor by remember {
mutableStateOf(HsvColor.from(initialColor))
}

val finish = {
onColorChanged(currentColor.toColor())
Toast.makeText(
context,
"${currentColor.toColor().toArgb()}",
Toast.LENGTH_LONG
).show()
isVisible.value = false
}

Expand Down
Loading

0 comments on commit 4b4059d

Please sign in to comment.