Jelajahi Sumber

1. 切换轮廓编辑模式。
2. 绘制锚点。

Ulric 3 minggu lalu
induk
melakukan
245a68909e

+ 71 - 0
app/src/main/java/com/ys/imageProcess/ui/work/AnchorLayer.kt

@@ -0,0 +1,71 @@
+package com.ys.imageProcess.ui.work
+
+import android.content.ContentValues.TAG
+import android.graphics.Point
+import android.graphics.PointF
+import android.nfc.Tag
+import android.util.Log
+import androidx.compose.foundation.Canvas
+import androidx.compose.foundation.layout.BoxWithConstraints
+import androidx.compose.foundation.layout.Spacer
+import androidx.compose.foundation.layout.fillMaxSize
+import androidx.compose.foundation.layout.width
+import androidx.compose.runtime.Composable
+import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.graphics.Color
+import androidx.compose.ui.graphics.Path
+import androidx.compose.ui.graphics.drawscope.DrawScope
+import androidx.compose.ui.graphics.drawscope.Fill
+import androidx.compose.ui.graphics.drawscope.Stroke
+
+@Composable
+fun AnchorLayer(
+    modifier: Modifier = Modifier,
+    anchors: List<Point> = listOf(),
+    imgOffset: Offset = Offset(0f, 0f),
+    imgScale: Float = 1f
+) {
+    BoxWithConstraints(modifier) {
+        Spacer(modifier = Modifier.width(maxWidth))
+
+        val p = PointF(200f, 200f)
+        val offsetX = p.x - maxWidth.value / 2
+        val offsetY = p.y - maxHeight.value / 2
+
+        val offsetX1 = offsetX * imgScale + imgOffset.x
+        val offsetY1 = offsetY * imgScale + imgOffset.y
+        val p1 =
+            PointF(
+                offsetX1 + maxWidth.value / 2,
+                offsetY1 + maxHeight.value / 2
+            )
+
+
+        Canvas(modifier.fillMaxSize()) {
+            drawPolygon(p1)
+        }
+    }
+}
+
+private fun DrawScope.drawPolygon(
+    point: PointF
+) {
+    val d = density
+    val path = Path().apply {
+        moveTo(point.x * d, point.y * d)
+        lineTo((point.x + 10) * d, (point.y + 10) * d)
+    }
+
+    drawPath(
+        path = path,
+        color = Color.Yellow,
+        style = Fill
+    )
+
+    drawPath(
+        path = path,
+        color = Color.Black,
+        style = Stroke(1f)
+    )
+}

+ 69 - 13
app/src/main/java/com/ys/imageProcess/ui/work/CanvasView.kt

@@ -1,10 +1,13 @@
 package com.ys.imageProcess.ui.work
 
+import android.graphics.Point
 import android.graphics.PointF
 import androidx.compose.foundation.Canvas
 import androidx.compose.foundation.layout.fillMaxSize
 import androidx.compose.runtime.Composable
 import androidx.compose.ui.Modifier
+import androidx.compose.ui.geometry.Offset
+import androidx.compose.ui.geometry.Rect
 import androidx.compose.ui.graphics.Color
 import androidx.compose.ui.graphics.Path
 import androidx.compose.ui.graphics.drawscope.DrawScope
@@ -12,6 +15,7 @@ import androidx.compose.ui.graphics.drawscope.Fill
 import androidx.compose.ui.graphics.drawscope.Stroke
 import androidx.compose.ui.tooling.preview.Preview
 import com.ys.imageProcess.ui.theme.ImageProcTheme
+import kotlin.math.abs
 
 @Composable
 fun CanvasView(
@@ -20,47 +24,99 @@ fun CanvasView(
     length: List<PointF> = listOf(),
     width: List<PointF> = listOf(),
     fillColor: Color = Color.Transparent,
-    strokeWidth: Float = 2f,
+    scale: Float = 1f,
     state: ImageState = ImageState()
 ) {
     Canvas(modifier.fillMaxSize()) {
+        val strokeWidth = 5 / scale
         if (state.showContour) {
-            drawPolygon(contour, fillColor, Color.Green, strokeWidth)
+            drawPolygon(contour, fillColor, Color.Green, strokeWidth, state.editMode)
         }
         if (state.showWidth) {
-            drawPolygon(width, fillColor, Color.Blue, strokeWidth)
+            drawPolygon(width, fillColor, Color.Blue, strokeWidth, state.editMode)
         }
         if (state.showLength) {
-            drawPolygon(length, fillColor, Color.Red, strokeWidth)
+            drawPolygon(length, fillColor, Color.Red, strokeWidth, state.editMode)
         }
+
     }
 }
 
-fun DrawScope.drawPolygon(
+private fun DrawScope.drawPolygon(
     points: List<PointF>,
     fillColor: Color,
     strokeColor: Color,
     strokeWidth: Float,
+    showAnchors: Boolean = false,
     closed: Boolean = false
 ) {
     val d = density
     val path = Path().apply {
         if (points.isNotEmpty()) {
-            moveTo(points[0].x * d, points[0].y * d)
-            for (i in 1 until points.size) {
-                lineTo(points[i].x * d, points[i].y * d)
+            for (i in points.indices) {
+                val x = points[i].x * d
+                val y = points[i].y * d
+                if (i == 0) {
+                    moveTo(x, y)
+                } else {
+                    lineTo(x, y)
+                }
             }
             if (closed) {
                 close()
             }
+
+
+            if (showAnchors) {
+                val l = strokeWidth * 5
+
+                for (i in points.indices) {
+                    val x = points[i].x * d
+                    val y = points[i].y * d
+
+                    moveTo(x, y)
+                    val rect = Rect(Offset(x - l, y - l), Offset(x + l, y + l))
+                    addRect(rect)
+
+                }
+            }
+
+            //            var showRect = true
+            //            var lastRectIndex = -1
+            //            val l = strokeWidth * 5
+            //
+            //            for (i in points.indices) {
+            //                val x = points[i].x * d
+            //                val y = points[i].y * d
+            //                if (i > 0) {
+            //                    if (lastRectIndex >= 0) {
+            //                        val lastRectX = points[lastRectIndex].x * d
+            //                        val lastRectY = points[lastRectIndex].y * d
+            //                        showRect =
+            //                            abs(lastRectX - x) > l * 4 || abs(lastRectY - y) > l * 4
+            //                        showRect = true
+            //                    }
+            //                    if (showRect) {
+            //                        lastRectIndex = i
+            //                    }
+            //                }
+            //
+            //
+            //                if (showRect) {
+            //                    moveTo(x, y)
+            //                    val rect = Rect(Offset(x - l, y - l), Offset(x + l, y + l))
+            //                    addRect(rect)
+            //                }
+
+            //            }
         }
     }
 
-    drawPath(
-        path = path,
-        color = fillColor,
-        style = Fill
-    )
+//    drawPath(
+//        path = path,
+//        color = fillColor,
+//        style = Fill
+//    )
 
     drawPath(
         path = path,

+ 3 - 1
app/src/main/java/com/ys/imageProcess/ui/work/CentralImageView.kt

@@ -30,6 +30,7 @@ fun CentralImageView(
     canvasSize: Size = Size(0f, 0f),
     data: ProcessedData = ProcessedData(),
     imageState: ImageState = ImageState(),
+    scale: Float = 1f,
     viewModel: CentralImageViewModel = viewModel(),
 ) {
     LaunchedEffect(data) {
@@ -57,7 +58,8 @@ fun CentralImageView(
                 contour = contour,
                 width = width,
                 length = length,
-                state = imageState
+                state = imageState,
+                scale = scale
             )
         }
     }

+ 6 - 4
app/src/main/java/com/ys/imageProcess/ui/work/ViewToolBar.kt

@@ -29,7 +29,8 @@ import com.ys.imageProcess.ui.work.ViewAction.*
  * @property ShowContour 显示轮廓
  */
 enum class ViewAction {
-    Back, ZoomIn, ZoomOut, FitScreen, ShowContour, ShowLength, ShowWidth, ToEdit;
+    Back, ZoomIn, ZoomOut, FitScreen, ShowContour, ShowLength, ShowWidth,
+    SwitchEdit;
 
     fun icon(): Int {
         return when (this) {
@@ -40,7 +41,7 @@ enum class ViewAction {
             ShowContour -> R.drawable.show_contour
             ShowLength -> R.drawable.show_length
             ShowWidth -> R.drawable.show_width2
-            ToEdit -> R.drawable.edit_path2
+            SwitchEdit -> R.drawable.edit_path2
         }
     }
 }
@@ -50,7 +51,8 @@ data class ImageState(
     val isFitScreen: Boolean = true,
     val showContour: Boolean = true,
     val showLength: Boolean = true,
-    val showWidth: Boolean = true
+    val showWidth: Boolean = true,
+    val editMode: Boolean = false,
 )
 
 @Composable
@@ -78,7 +80,7 @@ fun ViewToolBar(
                 ShowContour -> if (state.showContour) Blue else Color.DarkGray
                 ShowLength -> if (state.showLength) Blue else Color.DarkGray
                 ShowWidth -> if (state.showWidth) Blue else Color.DarkGray
-                ToEdit -> Color.DarkGray
+                SwitchEdit -> if (state.editMode) Blue else Color.DarkGray
             }
 
             Button(

+ 10 - 1
app/src/main/java/com/ys/imageProcess/ui/work/WorkScreen.kt

@@ -110,7 +110,16 @@ fun WorkScreen(
                         it,
                         canvasSize,
                         processedData,
-                        imageState
+                        imageState,
+                        scale
+                    )
+
+                    AnchorLayer(
+                        Modifier
+                            .fillMaxSize()
+                            .background(Color(0x88888888)),
+                        imgOffset = offset,
+                        imgScale = scale
                     )
 
                     Text(

+ 2 - 1
app/src/main/java/com/ys/imageProcess/viewModel/WorkViewModel.kt

@@ -215,7 +215,8 @@ class WorkViewModel : ViewModel() {
             ViewAction.ShowWidth -> imageState.value =
                 imageState.value.copy(showWidth = !imageState.value.showWidth)
 
-            ViewAction.ToEdit -> {}
+            ViewAction.SwitchEdit -> imageState.value =
+                imageState.value.copy(editMode = !imageState.value.editMode)
         }
 
         updateVisibleArea()