修改模式切换流程
This commit is contained in:
@@ -3,12 +3,17 @@ package com.sw.dualscreen.activity
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.graphics.Typeface
|
||||
import android.net.Uri
|
||||
import android.view.View
|
||||
import android.view.inputmethod.EditorInfo
|
||||
import android.view.inputmethod.InputMethodManager
|
||||
import android.widget.Toast
|
||||
import androidx.activity.viewModels
|
||||
import androidx.camera.view.PreviewView
|
||||
import androidx.core.net.toUri
|
||||
import androidx.core.view.updateLayoutParams
|
||||
import androidx.lifecycle.lifecycleScope
|
||||
import androidx.recyclerview.widget.GridLayoutManager
|
||||
import com.example.utils.FloatBase64Utils
|
||||
@@ -19,7 +24,9 @@ import com.sw.dualscreen.adapter.GridSpacingItemDecoration
|
||||
import com.sw.dualscreen.adapter.dpToPx
|
||||
import com.sw.dualscreen.databinding.ActivityFoodCollectionBinding
|
||||
import com.sw.dualscreen.databinding.ItemSearchFoodInfoBinding
|
||||
import com.sw.dualscreen.databinding.LayoutCameraPreviewBinding
|
||||
import com.sw.dualscreen.ext.clickWithDebounce
|
||||
import com.sw.dualscreen.ext.dp
|
||||
import com.sw.dualscreen.model.response.FoodInfo
|
||||
import com.sw.dualscreen.objbox.Food
|
||||
import com.sw.dualscreen.objbox.FoodCollectionBean
|
||||
@@ -28,6 +35,7 @@ import com.sw.dualscreen.objbox.ObjectBox
|
||||
import com.sw.dualscreen.utils.BitmapCropper
|
||||
import com.sw.dualscreen.utils.BitmapSaver
|
||||
import com.sw.dualscreen.utils.CameraHelper
|
||||
import com.sw.dualscreen.utils.CameraUtils
|
||||
import com.sw.dualscreen.utils.Debouncer
|
||||
import com.sw.dualscreen.utils.ImageUtil
|
||||
import com.sw.dualscreen.viewmodel.BaseViewModel
|
||||
@@ -46,17 +54,19 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
private val viewModel by viewModels<UserViewModel>()
|
||||
private var selectedFoodId: String? = ""
|
||||
private var selectedFoodName: String? = ""
|
||||
private val NO_MEAN_RGB = floatArrayOf(0.0f, 0.0f, 0.0f)
|
||||
private val NO_STD_RGB = floatArrayOf(1.0f, 1.0f, 1.0f)
|
||||
|
||||
private var module: Module? = null
|
||||
private var box: Box<Food>? = null
|
||||
private val foodCollectionList: MutableList<FoodCollectionBean> = mutableListOf()
|
||||
|
||||
private lateinit var cameraHelper: CameraHelper
|
||||
// private lateinit var cameraHelper: CameraHelper
|
||||
|
||||
private lateinit var foodAdapter: GenericItemAdapter<FoodInfo, ItemSearchFoodInfoBinding>
|
||||
private val foodList = mutableListOf<FoodInfo>() // 适配器内部维护的数据列表
|
||||
private val debouncer = Debouncer(2000)
|
||||
private lateinit var previewView: PreviewView
|
||||
private val cameraUtils: CameraUtils by lazy {
|
||||
CameraUtils(this)
|
||||
}
|
||||
|
||||
private val collectionAdapter: FoodCollectionAdapter by lazy {
|
||||
FoodCollectionAdapter(foodCollectionList).apply {
|
||||
@@ -67,9 +77,15 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
// }
|
||||
// }
|
||||
addOnItemChildClickListener(R.id.ivDelete) { _, _, position ->
|
||||
list.removeAt(position)
|
||||
collectionAdapter.notifyItemRemoved(position)
|
||||
collectionAdapter.notifyItemRangeChanged(position, list.size)
|
||||
// list.removeAt(position)
|
||||
// collectionAdapter.notifyItemRemoved(position)
|
||||
// collectionAdapter.notifyItemRangeChanged(position, list.size)
|
||||
foodCollectionList[position].let {
|
||||
it.bitmap = null
|
||||
it.isShowCamera = true
|
||||
it.isFinish = false
|
||||
}
|
||||
notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -82,54 +98,77 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
return ActivityFoodCollectionBinding.inflate(layoutInflater)
|
||||
}
|
||||
|
||||
private fun cameraCallback(uri:Uri){
|
||||
private val cameraCallback: (Uri) -> Unit = { uri ->
|
||||
val index = foodCollectionList.indexOfFirst { it.bitmap == null }
|
||||
if (index == -1) {
|
||||
ToastUtils.showToast("每次只允许保存6条数据")
|
||||
return
|
||||
rerurn@ cameraCallback
|
||||
}
|
||||
ImageUtil.uriToBitmap(this, uri)?.let { bitmap ->
|
||||
val cropBitmap = BitmapCropper.cropCenter(
|
||||
original = bitmap,
|
||||
targetWidth = 1300, targetHeight = 900,
|
||||
//offsetX = 30, offsetY = 100
|
||||
)
|
||||
// val cropBitmap = BitmapCropper.cropCenter(
|
||||
// original = bitmap,
|
||||
// targetWidth = 1300, targetHeight = 900,
|
||||
// //offsetX = 30, offsetY = 100
|
||||
// )
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
cropBitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
bitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
|
||||
|
||||
foodCollectionList[index].let {
|
||||
it.bitmap = cropBitmap
|
||||
it.bitmap = bitmap
|
||||
it.isShowCamera = false
|
||||
it.imageUri = file?.toUri()
|
||||
}
|
||||
collectionAdapter.notifyItemChanged(index)
|
||||
}
|
||||
}
|
||||
override fun initialize() {
|
||||
|
||||
// 初始化 CameraHelper
|
||||
cameraHelper = CameraHelper(
|
||||
context = this,
|
||||
caller = this,
|
||||
authority = "${packageName}.fileprovider"
|
||||
) { uri, path ->
|
||||
//if (foodCollectionList.size < 6) {
|
||||
// val insertIndex = if (foodCollectionList.isEmpty()) 0 else foodCollectionList.size - 1
|
||||
// foodCollectionList.add(insertIndex, FoodCollectionBean(imageUri = uri))
|
||||
//} else {
|
||||
// foodCollectionList[foodCollectionList.size - 1] = FoodCollectionBean(imageUri = uri)
|
||||
//}
|
||||
//collectionAdapter.notifyDataSetChanged()
|
||||
cameraCallback(uri)
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun takePhoto() {
|
||||
val count = foodCollectionList.count { it.bitmap != null }
|
||||
if (count == 6) {
|
||||
ToastUtils.showToast("每次只允许保存6条数据")
|
||||
return
|
||||
}
|
||||
cameraUtils.takePhoto(cameraCallback)
|
||||
}
|
||||
|
||||
override fun initialize() {
|
||||
cameraUtils.initCamera()
|
||||
val previewBinding =
|
||||
LayoutCameraPreviewBinding.inflate(layoutInflater, binding.flCameraPreview)
|
||||
previewView = previewBinding.previewView.also {
|
||||
it.updateLayoutParams {
|
||||
width = 180.dp
|
||||
height = 180.dp
|
||||
}
|
||||
}
|
||||
cameraUtils.setPreviewController(previewView)
|
||||
// 初始化 CameraHelper
|
||||
// cameraHelper = CameraHelper(
|
||||
// context = this,
|
||||
// caller = this,
|
||||
// authority = "${packageName}.fileprovider"
|
||||
// ) { uri, path ->
|
||||
// //if (foodCollectionList.size < 6) {
|
||||
// // val insertIndex = if (foodCollectionList.isEmpty()) 0 else foodCollectionList.size - 1
|
||||
// // foodCollectionList.add(insertIndex, FoodCollectionBean(imageUri = uri))
|
||||
// //} else {
|
||||
// // foodCollectionList[foodCollectionList.size - 1] = FoodCollectionBean(imageUri = uri)
|
||||
// //}
|
||||
// //collectionAdapter.notifyDataSetChanged()
|
||||
// cameraCallback(uri)
|
||||
// }
|
||||
|
||||
binding.ivBack.setOnClickListener {
|
||||
val intent = Intent(this, MainActivity::class.java)
|
||||
startActivity(intent)
|
||||
finish()
|
||||
}
|
||||
foodCollectionList.add(FoodCollectionBean(isShowCamera = true))
|
||||
repeat(6) {
|
||||
foodCollectionList.add(FoodCollectionBean(isShowCamera = true))
|
||||
}
|
||||
binding.rvFoodCollection.let {
|
||||
it.layoutManager = GridLayoutManager(this, 3, GridLayoutManager.VERTICAL, false)
|
||||
it.adapter = collectionAdapter
|
||||
@@ -164,15 +203,17 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
}
|
||||
|
||||
binding.btnCollectedGoods.setOnClickListener {
|
||||
|
||||
startActivity(Intent(this, CollectedDataActivity::class.java))
|
||||
}
|
||||
binding.btnTakePhoto.clickWithDebounce {
|
||||
binding.btnTakePhoto.text = "拍照"
|
||||
val count = foodCollectionList.count { it.bitmap != null }
|
||||
if (count == 6) {
|
||||
ToastUtils.showToast("每次只允许保存6条数据")
|
||||
return@clickWithDebounce
|
||||
}
|
||||
cameraHelper.openCamera()
|
||||
// cameraHelper.openCamera()
|
||||
takePhoto()
|
||||
}
|
||||
binding.btnClearData.setOnClickListener { clearData() }
|
||||
foodAdapter = createAdapter()
|
||||
@@ -192,11 +233,11 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
//Loading.show(this)
|
||||
showWaitingDialog("加载中……")
|
||||
Thread {
|
||||
foodCollectionList.forEachIndexed { index, it ->
|
||||
|
||||
if (!it.isShowCamera)
|
||||
image2VectorTask(it.imageUri!!, index)
|
||||
}
|
||||
foodCollectionList
|
||||
.filter { it.bitmap != null }
|
||||
.forEachIndexed { index, it ->
|
||||
image2VectorTask(it, index)
|
||||
}
|
||||
runOnUiThread {
|
||||
window.decorView.postDelayed({
|
||||
//Loading.dismiss()
|
||||
@@ -206,44 +247,33 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun image2VectorTask(imageUri: Uri, position: Int) {
|
||||
if (module == null) {
|
||||
module =
|
||||
Module.load(FoodModule.copyAssetToCache(this, "best_embedding_model_mobile.pt"))
|
||||
}
|
||||
private fun initBox() {
|
||||
if (box == null) {
|
||||
box = ObjectBox.boxStore.boxFor(Food::class)
|
||||
}
|
||||
ImageUtil.uriToBitmap(this, imageUri)?.let { bitmap ->
|
||||
//val bitmap2 = BitmapCropper.cropCenter(bitmap!!, 500, 500)
|
||||
val inputTensor = TensorImageUtils.bitmapToFloat32Tensor(
|
||||
bitmap,
|
||||
NO_MEAN_RGB, // [0.485, 0.456, 0.406] TORCHVISION_NORM_MEAN_RGB
|
||||
NO_STD_RGB // [0.229, 0.224, 0.225] TORCHVISION_NORM_STD_RGB
|
||||
)
|
||||
val outputTensor = module!!.forward(IValue.from(inputTensor)).toTensor()
|
||||
}
|
||||
|
||||
val base64Str = FloatBase64Utils.floatArrayToBase64(outputTensor.dataAsFloatArray)
|
||||
Timber.tag("mzf1").e(base64Str)
|
||||
val imageVector = outputTensor.dataAsFloatArray
|
||||
box?.put(Food(name = selectedFoodName, foodIdx = 0, foodVector = imageVector))
|
||||
foodCollectionList[position].let {
|
||||
it.imageVector = imageVector
|
||||
it.isFinish = true
|
||||
private fun image2VectorTask(item: FoodCollectionBean, position: Int) {
|
||||
initBox()
|
||||
val imageVector = FoodModule.bitmap2FloatArray(item.bitmap!!)
|
||||
|
||||
Timber
|
||||
viewModel.postImageData(
|
||||
context,
|
||||
foodId = selectedFoodId.toString(),
|
||||
foodName = selectedFoodName.toString(),
|
||||
foodVector = base64Str,
|
||||
uri = imageUri
|
||||
)
|
||||
}
|
||||
runOnUiThread {
|
||||
collectionAdapter.notifyItemChanged(position)
|
||||
}
|
||||
Timber.tag("registerDataChange").e("box.all.size=${box?.all?.size}")
|
||||
val base64Str = FloatBase64Utils.floatArrayToBase64(imageVector)
|
||||
Timber.tag("mzf1").e(base64Str)
|
||||
// viewModel.postImageData(
|
||||
// context,
|
||||
// foodId = selectedFoodId.toString(),
|
||||
// foodName = selectedFoodName.toString(),
|
||||
// foodVector = base64Str,
|
||||
// uri = item.imageUri!!
|
||||
// )
|
||||
box?.put(Food(name = checkedItem!!.foodName, foodIdx = 0, foodVector = imageVector))
|
||||
foodCollectionList[position].let {
|
||||
it.imageVector = imageVector
|
||||
it.isFinish = true
|
||||
}
|
||||
|
||||
runOnUiThread {
|
||||
collectionAdapter.notifyItemChanged(position)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,6 +288,8 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
super.registerDataChange()
|
||||
lifecycleScope.launch {
|
||||
viewModel.searchFoodInfoList.collect {
|
||||
// foodList.clear()
|
||||
// foodList.addAll(it)
|
||||
foodAdapter.updateData(it)
|
||||
}
|
||||
}
|
||||
@@ -294,7 +326,9 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
}
|
||||
)
|
||||
}
|
||||
|
||||
private var clickIndex = -1
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun clearData() {
|
||||
foodCollectionList.forEach {
|
||||
@@ -306,9 +340,27 @@ class FoodCollectionActivity : BaseActivity<ActivityFoodCollectionBinding>() {
|
||||
|
||||
clickIndex = -1
|
||||
binding.editFoodName.setText("")
|
||||
foodAdapter.updateData(mutableListOf())
|
||||
foodAdapter.notifyDataSetChanged()
|
||||
// foodList.clear()
|
||||
// foodAdapter.updateData(mutableListOf())
|
||||
// foodAdapter.notifyDataSetChanged()
|
||||
//loadEmptyView()
|
||||
}
|
||||
|
||||
override fun onResume() {
|
||||
super.onResume()
|
||||
cameraUtils.bind()
|
||||
binding.llCameraFlag.run {
|
||||
visibility = View.VISIBLE
|
||||
postDelayed({
|
||||
visibility = View.GONE
|
||||
}, 3000)
|
||||
}
|
||||
}
|
||||
|
||||
override fun onPause() {
|
||||
super.onPause()
|
||||
cameraUtils.unbind()
|
||||
binding.llCameraFlag.visibility = View.VISIBLE
|
||||
}
|
||||
|
||||
}
|
||||
@@ -235,15 +235,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
ImageUtil.uriToBitmap(this, photoUri)?.let { bitmap ->
|
||||
Timber.d("registerDataChange photoUri 拿到bitmap")
|
||||
val bmp = BitmapCropper.cropCenter(bitmap, 1300, 900)
|
||||
// val bmp = BitmapCropper.cropCenter(bitmap, 1300, 900)
|
||||
Timber.d("registerDataChange photoUri bitmap裁剪完成")
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
bmp,
|
||||
bitmap,
|
||||
this,
|
||||
"IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.d("registerDataChange photoUri bitmap保存文件路径:${file?.absolutePath}")
|
||||
val resultList = FoodModule.queryFood(bmp)
|
||||
val resultList = FoodModule.queryFood(bitmap)
|
||||
Timber.d("registerDataChange photoUri 拿到识别数据")
|
||||
val foodName = resultList.joinToString(separator = ",")
|
||||
Timber.d("registerDataChange photoUri 识别数据名称:$foodName")
|
||||
|
||||
Reference in New Issue
Block a user