添加了图片拍照及识别逻辑

This commit is contained in:
zxj
2025-08-14 09:34:49 +08:00
parent 1ac73df8d9
commit 10d4a4a41d
16 changed files with 542 additions and 396 deletions
@@ -63,65 +63,27 @@ object InteractionUtils {
// ======================== 防抖处理 ========================
/**
* 防抖处理器
* 防抖工具类
* @param delayMillis 防抖延迟时间(毫秒)
*/
class Debouncer(
private val delayMillis: Long = 300L,
private val coroutineScope: CoroutineScope
) {
private var debounceJob: Job? = null
class Debouncer(private val delayMillis: Long) {
private var lastActionTime = 0L
/**
* 执行防抖操作
* @param block 要执行的代码块
* @return Boolean 是否实际执行了操作
*/
fun <T> debounce(value: T, action: (T) -> Unit) {
debounceJob?.cancel()
debounceJob = coroutineScope.launch {
delay(delayMillis)
action(value)
}
}
}
/**
* 记住防抖处理器
*/
@Composable
fun rememberDebouncer(
delayMillis: Long = 300L,
coroutineScope: CoroutineScope = rememberCoroutineScope()
): Debouncer {
return remember { Debouncer(delayMillis, coroutineScope) }
}
// ======================== 节流处理 ========================
/**
* 节流处理器
*/
class Throttler(private val timeoutMs: Long = 300L) {
private var lastRunTime: Long = 0
/**
* 执行节流操作
*/
fun throttle(block: () -> Unit) {
val now = System.currentTimeMillis()
if (now - lastRunTime > timeoutMs) {
lastRunTime = now
fun debounce(block: () -> Unit): Boolean {
val currentTime = System.currentTimeMillis()
if (currentTime - lastActionTime >= delayMillis) {
lastActionTime = currentTime
block()
return true
}
return false
}
}
/**
* 记住节流处理器
*/
@Composable
fun rememberThrottler(timeoutMs: Long = 300L): Throttler {
return remember { Throttler(timeoutMs) }
}
// ======================== 双击检测 ========================
/**
@@ -0,0 +1,100 @@
package com.sw.inbound.utils
import android.content.Context
import android.net.Uri
import androidx.camera.core.ImageCapture
import androidx.camera.core.ImageCaptureException
import androidx.camera.view.CameraController
import androidx.compose.runtime.Composable
import androidx.compose.runtime.remember
import androidx.compose.ui.platform.LocalContext
import androidx.core.content.ContextCompat
import timber.log.Timber
import java.io.File
/**
* 拍照工具类
* @param context Context 上下文
* @param cameraController CameraController 相机控制器
* @param onSuccess (Uri) -> Unit 拍照成功回调
* @param onError (String) -> Unit 拍照失败回调
*/
class PhotoCaptureHelper(
private val context: Context,
private val cameraController: CameraController,
private val onSuccess: (Uri) -> Unit = {},
private val onError: (String) -> Unit = {}
) {
/**
* 拍照方法
* @param fileNamePrefix 文件名前缀,默认为"IMG_"
* @param fileExtension 文件扩展名,默认为".jpg"
*/
fun takePhoto(
fileNamePrefix: String = "IMG_",
fileExtension: String = ".jpg"
) {
Timber.d("开始拍照采集")
try {
val executor = ContextCompat.getMainExecutor(context)
val cacheDir = context.cacheDir
val photoFile = File.createTempFile(
"${fileNamePrefix}${System.currentTimeMillis()}",
fileExtension,
cacheDir
)
val outputOptions = ImageCapture.OutputFileOptions.Builder(photoFile).build()
cameraController.takePicture(
outputOptions,
executor,
object : ImageCapture.OnImageSavedCallback {
override fun onImageSaved(outputFileResults: ImageCapture.OutputFileResults) {
val photoUri = outputFileResults.savedUri ?: Uri.fromFile(photoFile)
Timber.d("照片保存成功: $photoUri")
onSuccess(photoUri)
}
override fun onError(exception: ImageCaptureException) {
val errorMsg = "拍照失败: ${exception.message}"
Timber.e(exception, errorMsg)
onError(errorMsg)
}
}
)
} catch (e: Exception) {
val errorMsg = "创建临时文件失败: ${e.message}"
Timber.e(e, errorMsg)
onError(errorMsg)
}
}
}
/**
* 用于Compose的拍照Hook
* @param cameraController CameraController 相机控制器
* @param onSuccess (Uri) -> Unit 拍照成功回调
* @param onError (String) -> Unit 拍照失败回调
* @return Pair<PhotoCaptureHelper, () -> Unit> 返回工具类实例和拍照函数
*/
@Composable
fun rememberPhotoCapture(
cameraController: CameraController,
onSuccess: (Uri) -> Unit = {},
onError: (String) -> Unit = {}
): Pair<PhotoCaptureHelper, () -> Unit> {
val context = LocalContext.current
val photoCaptureHelper = remember {
PhotoCaptureHelper(
context = context,
cameraController = cameraController,
onSuccess = onSuccess,
onError = onError
)
}
return Pair(photoCaptureHelper) { photoCaptureHelper.takePhoto() }
}