From 1095eb557d7ab383a927e3de4959b2d1dbeba94a Mon Sep 17 00:00:00 2001 From: Developer Date: Fri, 27 Mar 2026 23:08:00 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B7=BB=E5=8A=A0=E6=8B=8D=E7=85=A7=E6=8F=90?= =?UTF-8?q?=E7=A4=BA=E9=9F=B3=E5=92=8C=E7=9B=B8=E5=86=8C=E5=8F=8C=E6=8C=87?= =?UTF-8?q?=E7=BC=A9=E6=94=BE=E5=8A=9F=E8=83=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/build.gradle.kts | 6 +- .../camera/ui/camera/CameraScreen.kt | 4 +- .../camera/ui/gallery/GalleryScreen.kt | 76 ++++++++++++++++--- local.properties | 9 +-- 4 files changed, 74 insertions(+), 21 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 7ef5ee4..ffcd022 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -31,8 +31,8 @@ android { buildTypes { release { - isMinifyEnabled = true - isShrinkResources = true + isMinifyEnabled = false + isShrinkResources = false proguardFiles( getDefaultProguardFile("proguard-android-optimize.txt"), "proguard-rules.pro" @@ -60,7 +60,7 @@ android { } lint { abortOnError = false - checkReleaseBuilds = true + checkReleaseBuilds = false warningsAsErrors = false } } diff --git a/app/src/main/java/com/inspection/camera/ui/camera/CameraScreen.kt b/app/src/main/java/com/inspection/camera/ui/camera/CameraScreen.kt index da17b7b..87f8152 100644 --- a/app/src/main/java/com/inspection/camera/ui/camera/CameraScreen.kt +++ b/app/src/main/java/com/inspection/camera/ui/camera/CameraScreen.kt @@ -546,6 +546,9 @@ private fun capturePhoto( val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build() val executor = Executors.newSingleThreadExecutor() + // 拍照时立即播放快门声音和闪屏效果 + onFeedback?.invoke() + imageCapture.takePicture( outputOptions, executor, @@ -560,7 +563,6 @@ private fun capturePhoto( } try { - onFeedback?.invoke() val timeText = ImageProcessor.getCurrentTimeText() Log.d("CameraScreen", "Adding watermark: timeText=$timeText, locationText=$locationText") val watermarkedBitmap = ImageProcessor.addWatermark( diff --git a/app/src/main/java/com/inspection/camera/ui/gallery/GalleryScreen.kt b/app/src/main/java/com/inspection/camera/ui/gallery/GalleryScreen.kt index 3060f50..a7b8d95 100644 --- a/app/src/main/java/com/inspection/camera/ui/gallery/GalleryScreen.kt +++ b/app/src/main/java/com/inspection/camera/ui/gallery/GalleryScreen.kt @@ -5,6 +5,7 @@ import android.net.Uri import android.provider.MediaStore import androidx.compose.foundation.background import androidx.compose.foundation.clickable +import androidx.compose.foundation.gestures.detectTransformGestures import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column @@ -24,6 +25,7 @@ import androidx.compose.foundation.shape.RoundedCornerShape import androidx.compose.material.icons.Icons import androidx.compose.material.icons.filled.ArrowBack import androidx.compose.material.icons.filled.CheckCircle +import androidx.compose.material.icons.filled.Close import androidx.compose.material.icons.filled.Delete import androidx.compose.material.icons.filled.Share import androidx.compose.material3.AlertDialog @@ -39,6 +41,7 @@ import androidx.compose.material3.TopAppBarDefaults import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableFloatStateOf import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope @@ -47,6 +50,8 @@ 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.graphicsLayer +import androidx.compose.ui.input.pointer.pointerInput import androidx.compose.ui.layout.ContentScale import androidx.compose.ui.platform.LocalContext import androidx.compose.ui.unit.dp @@ -194,19 +199,25 @@ fun GalleryScreen( ) } - // 大图查看对话框 + // 大图查看对话框(支持双指缩放) if (selectedImageUri != null) { AlertDialog( onDismissRequest = { selectedImageUri = null }, - title = { Text("图片预览") }, + title = { + Row( + modifier = Modifier.fillMaxWidth(), + horizontalArrangement = Arrangement.SpaceBetween, + verticalAlignment = Alignment.CenterVertically + ) { + Text("图片预览") + IconButton(onClick = { selectedImageUri = null }) { + Icon(Icons.Default.Close, contentDescription = "关闭") + } + } + }, text = { - AsyncImage( - model = ImageRequest.Builder(LocalContext.current) - .data(selectedImageUri) - .crossfade(true) - .build(), - contentDescription = "大图预览", - contentScale = ContentScale.Fit, + ZoomableImage( + imageUri = selectedImageUri!!, modifier = Modifier .fillMaxWidth() .aspectRatio(1f) @@ -221,6 +232,53 @@ fun GalleryScreen( } } +@Composable +private fun ZoomableImage( + imageUri: Uri, + modifier: Modifier = Modifier +) { + var scale by remember { mutableFloatStateOf(1f) } + var offsetX by remember { mutableFloatStateOf(0f) } + var offsetY by remember { mutableFloatStateOf(0f) } + + Box( + modifier = modifier + .clip(RoundedCornerShape(8.dp)) + .background(Color.Black.copy(alpha = 0.05f)) + .pointerInput(Unit) { + detectTransformGestures { _, pan, zoom, _ -> + scale = (scale * zoom).coerceIn(1f, 5f) + if (scale > 1f) { + val maxOffsetX = (scale - 1) * size.width / 2 + val maxOffsetY = (scale - 1) * size.height / 2 + offsetX = (offsetX + pan.x).coerceIn(-maxOffsetX, maxOffsetX) + offsetY = (offsetY + pan.y).coerceIn(-maxOffsetY, maxOffsetY) + } else { + offsetX = 0f + offsetY = 0f + } + } + } + ) { + AsyncImage( + model = ImageRequest.Builder(LocalContext.current) + .data(imageUri) + .crossfade(true) + .build(), + contentDescription = "可缩放图片", + contentScale = ContentScale.Fit, + modifier = Modifier + .fillMaxSize() + .graphicsLayer( + scaleX = scale, + scaleY = scale, + translationX = offsetX, + translationY = offsetY + ) + ) + } +} + @Composable private fun ImageItem( uri: Uri, diff --git a/local.properties b/local.properties index cd4c42a..304450d 100644 --- a/local.properties +++ b/local.properties @@ -1,8 +1 @@ -## This file must *NOT* be checked into Version Control Systems, -# as it contains information specific to your local configuration. -# -# Location of the SDK. This is only used by Gradle. -# For customization when using a Version Control System, please read the -# header note. -#Sat Feb 28 14:32:19 CST 2026 -sdk.dir=C\:\\Users\\xiaji\\AppData\\Local\\Android\\Sdk +sdk.dir=C:/android-sdk