优化
This commit is contained in:
@@ -29,7 +29,7 @@ class MyApp : App() {
|
||||
CrashHandler.init(this)
|
||||
|
||||
SensorScaleUtils.startScale()
|
||||
//addActivityLifecycleListener()
|
||||
addActivityLifecycleListener()
|
||||
}
|
||||
|
||||
private fun addActivityLifecycleListener() {
|
||||
|
||||
@@ -106,6 +106,9 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
private val adapter by lazy {
|
||||
SearchFoodAdapter(searchFoodList).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
if (searchFoodList[position].isChecked) {
|
||||
return@setOnItemClickListener
|
||||
}
|
||||
searchFoodList.forEachIndexed { index, info ->
|
||||
searchFoodList[index].isChecked = index == position
|
||||
}
|
||||
@@ -373,12 +376,14 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
showWaitingDialog("识别中,请稍后……")
|
||||
takePhoto(
|
||||
successCallback = { photoUri ->
|
||||
onTakePhotoSuccess(photoUri)
|
||||
Thread{
|
||||
onTakePhotoSuccess(photoUri)
|
||||
}.start()
|
||||
failCount = 0
|
||||
}, failureCallback = {
|
||||
runOnUiThread {
|
||||
if (failCount >= 10) {
|
||||
ToastUtils.showToast("相机异常,请稍后重试")
|
||||
//ToastUtils.showToast("相机异常,请稍后重试")
|
||||
shutdownCamera()
|
||||
setupCamera()
|
||||
return@runOnUiThread
|
||||
@@ -774,6 +779,7 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
ToastUtils.showToast("您好,当前重量不足一份")
|
||||
return
|
||||
}
|
||||
showWaitingDialog("加载中,请稍候……")
|
||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
val order = FoodOrder(
|
||||
deviceId = GlobalData.deviceId,
|
||||
@@ -790,19 +796,30 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
//即放即取-1,称重-2
|
||||
mode = if (pickupMode == 1) 1 else 2
|
||||
)
|
||||
debouncer.debounce {
|
||||
submitOrder(order, block)
|
||||
}
|
||||
}
|
||||
|
||||
private fun submitOrder(order: FoodOrder, block: () -> Unit) {
|
||||
viewModel.createOrder(order) { orderId ->
|
||||
runOnUiThread {
|
||||
if (orderId.isBlank()) {
|
||||
//ToastUtils.showToast("订单id为空")
|
||||
return@runOnUiThread
|
||||
}
|
||||
foodOrderId = orderId
|
||||
block()
|
||||
binding.root.postDelayed({
|
||||
hideWaitingDialog()
|
||||
if (orderId.isBlank()) {
|
||||
//ToastUtils.showToast("订单id为空")
|
||||
return@postDelayed
|
||||
}
|
||||
foodOrderId = orderId
|
||||
block()
|
||||
|
||||
if (checkedItem!!.isFromSearch == true) {
|
||||
//当前菜名为手动搜索选择,非识别结果,保存向量数据
|
||||
saveFoodVector(checkedItem!!)
|
||||
}
|
||||
if (checkedItem!!.isFromSearch == true) {
|
||||
//当前菜名为手动搜索选择,非识别结果,保存向量数据
|
||||
Thread{
|
||||
saveFoodVector(checkedItem!!)
|
||||
}.start()
|
||||
}
|
||||
}, 300)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -916,11 +933,12 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
*/
|
||||
private fun saveFoodVector(foodInfo: FoodInfo) {
|
||||
try {
|
||||
lastPhotoUri?.let { uri ->
|
||||
uri2File(uri) { imageFile, imageVector ->
|
||||
runBlocking {
|
||||
uploadCollectFoodPics(foodInfo, imageFile, imageVector)
|
||||
}
|
||||
if (lastPhotoUri == null) {
|
||||
return
|
||||
}
|
||||
uri2File(lastPhotoUri!!) { imageFile, imageVector ->
|
||||
runBlocking {
|
||||
uploadCollectFoodPics(foodInfo, imageFile, imageVector)
|
||||
}
|
||||
}
|
||||
} catch (e: Exception) {
|
||||
@@ -974,15 +992,17 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
loadRemindDialog("返回的id:${idList[0]}已存在")
|
||||
return
|
||||
}
|
||||
box.put(
|
||||
Food(
|
||||
collectId = idList[0],
|
||||
foodId = foodId,
|
||||
foodName = foodName,
|
||||
foodVector = imageVector,
|
||||
version = foodModelVersion
|
||||
Thread {
|
||||
box.put(
|
||||
Food(
|
||||
collectId = idList[0],
|
||||
foodId = foodId,
|
||||
foodName = foodName,
|
||||
foodVector = imageVector,
|
||||
version = foodModelVersion
|
||||
)
|
||||
)
|
||||
)
|
||||
}.start()
|
||||
}
|
||||
|
||||
private fun loadRemindDialog(msg: String) {
|
||||
@@ -1193,7 +1213,6 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
startTime = System.currentTimeMillis()
|
||||
Timber.d("registerDataChange photoUri = ${photoUri.path}")
|
||||
// viewModel.getIdentifiedFoodList()
|
||||
|
||||
ImageUtil.uriToBitmap(this, photoUri)?.let { bitmap ->
|
||||
Timber.tag(TAG).d("main,uriToBitmap耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
@@ -1201,19 +1220,15 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
// val bmp = BitmapCropper.cropCenter(bitmap, 1300, 900)
|
||||
Timber.d("registerDataChange photoUri bitmap裁剪完成")
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
bitmap,
|
||||
this,
|
||||
"IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
bitmap, this, "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.tag(TAG)
|
||||
.d("main,saveToAppFilesDir耗时:${System.currentTimeMillis() - startTime}")
|
||||
Timber.tag(TAG).d("main,saveToAppFilesDir耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
Timber.d("registerDataChange photoUri bitmap保存文件路径:${file?.absolutePath}")
|
||||
//val nameList = FoodModule.queryFood(bitmap)
|
||||
val scoreList = FoodModule.getFoodScoreList(bitmap)
|
||||
val recDataJson = GsonUtils.toJson(scoreList)
|
||||
Timber.tag(TAG)
|
||||
.d("main,getFoodScoreList耗时:${System.currentTimeMillis() - startTime}")
|
||||
Timber.tag(TAG).d("main,getFoodScoreList耗时:${System.currentTimeMillis() - startTime}")
|
||||
startTime = System.currentTimeMillis()
|
||||
Timber.d("registerDataChange photoUri 拿到识别数据:$recDataJson")
|
||||
val nameList = scoreList.map { it.name }
|
||||
@@ -1221,19 +1236,23 @@ class MainActivity : BaseActivity<ActivityMainBinding>() {
|
||||
|
||||
hideWaitingDialog()
|
||||
Timber.d("registerDataChange photoUri 识别数据名称:$foodName")
|
||||
binding.flPay.run {
|
||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
//0-计费,1-不计费
|
||||
if (chargeMode == 0) visible() else gone()
|
||||
runOnUiThread {
|
||||
binding.flPay.run {
|
||||
val chargeMode = SPUtil.getInstance().get(GlobalKey.KEY_CHARGE_MODE, 0)
|
||||
//0-计费,1-不计费
|
||||
if (chargeMode == 0) visible() else gone()
|
||||
}
|
||||
}
|
||||
if (TextUtils.isEmpty(foodName)) {
|
||||
LightManager.closeGreenLight()
|
||||
LightManager.closeRedLight()
|
||||
//binding.layoutRescan.visibility = View.VISIBLE
|
||||
|
||||
binding.tvToSearch.let {
|
||||
it.text = "未识别到,手动搜索"
|
||||
it.visible()
|
||||
runOnUiThread {
|
||||
binding.tvToSearch.let {
|
||||
it.text = "未识别到,手动搜索"
|
||||
it.visible()
|
||||
}
|
||||
}
|
||||
} else {
|
||||
//binding.layoutRescan.visibility = View.GONE
|
||||
|
||||
@@ -3,6 +3,7 @@ package com.sw.dualscreen.activity.fragment
|
||||
import android.annotation.SuppressLint
|
||||
import android.content.Context
|
||||
import android.content.Intent
|
||||
import android.graphics.Bitmap
|
||||
import android.net.Uri
|
||||
import android.view.LayoutInflater
|
||||
import android.view.View
|
||||
@@ -27,6 +28,7 @@ import com.sw.dualscreen.objbox.Food
|
||||
import com.sw.dualscreen.objbox.FoodCollectionBean
|
||||
import com.sw.dualscreen.objbox.FoodModule
|
||||
import com.sw.dualscreen.objbox.ObjectBox
|
||||
import com.sw.dualscreen.utils.BitmapCropper
|
||||
import com.sw.dualscreen.utils.BitmapSaver
|
||||
import com.sw.dualscreen.utils.CameraUtils
|
||||
import com.sw.dualscreen.utils.Debouncer
|
||||
@@ -42,22 +44,24 @@ import okhttp3.RequestBody.Companion.toRequestBody
|
||||
import timber.log.Timber
|
||||
import kotlin.getValue
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
|
||||
companion object {
|
||||
private const val TAG = "CollectFragment"
|
||||
const val MAX_COUNT = 15
|
||||
const val MAX_COUNT = 9
|
||||
}
|
||||
|
||||
private var selectedFoodId: String? = ""
|
||||
private var selectedFoodName: String? = ""
|
||||
|
||||
private var box: Box<Food>?=null
|
||||
private var box: Box<Food>? = null
|
||||
fun initBox() {
|
||||
if (box == null) {
|
||||
box = ObjectBox.boxStore.boxFor(Food::class)
|
||||
}
|
||||
}
|
||||
|
||||
private val foodCollectionList = mutableListOf<FoodCollectionBean>().apply {
|
||||
repeat(MAX_COUNT) {
|
||||
add(FoodCollectionBean(isShowCamera = true))
|
||||
@@ -70,10 +74,9 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
private val searchFoodAdapter by lazy {
|
||||
SearchFoodAdapter(searchFoodList).apply {
|
||||
setOnItemClickListener { adapter, view, position ->
|
||||
searchFoodList.forEachIndexed { index, item -> item.isChecked = index == position }
|
||||
checkedItem = searchFoodList[position]
|
||||
val isChecked = checkedItem!!.isChecked
|
||||
searchFoodList[position].isChecked = isChecked.not()
|
||||
notifyItemChanged(position)
|
||||
notifyDataSetChanged()
|
||||
selectedFoodId = checkedItem!!.foodId
|
||||
selectedFoodName = checkedItem!!.foodName
|
||||
}
|
||||
@@ -126,37 +129,11 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
collectionAdapter.notifyItemChanged(index)
|
||||
}
|
||||
// settingActivity?.hideWaitingDialog()
|
||||
ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
|
||||
// val cropBitmap = BitmapCropper.cropCenter(
|
||||
// original = bitmap,
|
||||
// targetWidth = 1300, targetHeight = 900,
|
||||
// //offsetX = 30, offsetY = 100
|
||||
// )
|
||||
val imageVector = try {
|
||||
FoodModule.bitmap2FloatArray(bitmap)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
ToastUtils.showToast("操作失败")
|
||||
settingActivity?.hideWaitingDialog()
|
||||
return@let
|
||||
Thread {
|
||||
ImageUtil.uriToBitmap(requireActivity(), uri)?.let { bitmap ->
|
||||
getImageVector(index, bitmap)
|
||||
}
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
bitmap, requireActivity(), "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
|
||||
|
||||
foodCollectionList[index].let {
|
||||
it.imageVector = imageVector
|
||||
it.bitmap = null
|
||||
it.isShowCamera = false
|
||||
it.imageFile = file
|
||||
}
|
||||
collectionAdapter.notifyItemChanged(index)
|
||||
if (bitmap.isRecycled.not()) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
settingActivity?.hideWaitingDialog()
|
||||
}
|
||||
}.start()
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
settingActivity?.hideWaitingDialog()
|
||||
@@ -164,6 +141,40 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun getImageVector(index: Int, bitmap: Bitmap) {
|
||||
// val bitmap = BitmapCropper.cropCenter(
|
||||
// original = srcBmp,
|
||||
// targetWidth = 900, targetHeight = 900,
|
||||
//// offsetX = 30, offsetY = 100
|
||||
// )
|
||||
val imageVector = try {
|
||||
FoodModule.bitmap2FloatArray(bitmap)
|
||||
} catch (e: Exception) {
|
||||
e.printStackTrace()
|
||||
ToastUtils.showToast("操作失败")
|
||||
settingActivity?.hideWaitingDialog()
|
||||
return
|
||||
}
|
||||
val file = BitmapSaver.saveToAppFilesDir(
|
||||
bitmap, requireActivity(), "IMG_CROP_${System.currentTimeMillis()}.jpg"
|
||||
)
|
||||
Timber.d("${this.javaClass.simpleName}-cameraCallback-裁剪bitmap保存文件路径:${file?.absolutePath}")
|
||||
|
||||
activity?.runOnUiThread {
|
||||
foodCollectionList[index].let {
|
||||
it.imageVector = imageVector
|
||||
it.bitmap = null
|
||||
it.isShowCamera = false
|
||||
it.imageFile = file
|
||||
}
|
||||
collectionAdapter.notifyItemChanged(index)
|
||||
}
|
||||
if (bitmap.isRecycled.not()) {
|
||||
bitmap.recycle()
|
||||
}
|
||||
settingActivity?.hideWaitingDialog()
|
||||
}
|
||||
|
||||
@SuppressLint("NotifyDataSetChanged")
|
||||
private fun takePhoto() {
|
||||
val count = foodCollectionList.count { it.bitmap != null }
|
||||
@@ -173,11 +184,19 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
}
|
||||
settingActivity?.showWaitingDialog("采集中……")
|
||||
cameraUtils.takePhoto(cameraCallback) { errMsg ->
|
||||
ToastUtils.showToast("拍照异常,请重新操作")
|
||||
settingActivity?.hideWaitingDialog()
|
||||
if (cameraErrorCount >= 10) {
|
||||
ToastUtils.showToast("拍照异常,请重新操作")
|
||||
cameraErrorCount = 0
|
||||
return@takePhoto
|
||||
}
|
||||
cameraErrorCount++
|
||||
takePhoto()
|
||||
}
|
||||
}
|
||||
|
||||
private var cameraErrorCount = 0
|
||||
|
||||
override fun initialize() {
|
||||
settingActivity = activity as SettingActivity
|
||||
cameraUtils.initCamera()
|
||||
@@ -256,65 +275,56 @@ class CollectFragment : BaseFragment<FragmentCollectBinding>() {
|
||||
params["foodName"] = checkedItem!!.foodName!!.toRequestBody()
|
||||
params["version"] = GlobalData.foodModelVersion.toRequestBody()
|
||||
|
||||
ImageUploader(
|
||||
totalList = foodCollectionList,
|
||||
uploadImage = { batch ->
|
||||
val files = batch.map { it.imageFile }
|
||||
val foodVectorList =
|
||||
batch.filter { it.imageVector != null }.map {
|
||||
it.imageVector!!.joinToString(
|
||||
separator = ",",
|
||||
prefix = "[",
|
||||
postfix = "]"
|
||||
)
|
||||
}
|
||||
val foodVectorJson =
|
||||
foodVectorList.joinToString(separator = ",", prefix = "[", postfix = "]")
|
||||
Timber.tag(TAG).d("json=$foodVectorJson")
|
||||
params["foodVector"] = foodVectorJson.toRequestBody()
|
||||
settingActivity?.viewModel?.uploadCollectFoodPics(files, params)
|
||||
},
|
||||
onProgress = { count, batch, idList ->
|
||||
//batch.forEach {
|
||||
// it.uploadSuccess = true
|
||||
//}
|
||||
runBlocking {
|
||||
activity?.runOnUiThread {
|
||||
settingActivity?.showWaitingDialog2("图片上传中$count/$totalFileCount")
|
||||
}
|
||||
val foodList = batch.mapIndexed { index, it ->
|
||||
Food(
|
||||
collectId = if (index < idList.size) idList[index] else null,
|
||||
foodId = checkedItem!!.foodId,
|
||||
foodName = checkedItem!!.foodName,
|
||||
foodVector = it.imageVector,
|
||||
version = GlobalData.foodModelVersion
|
||||
)
|
||||
}
|
||||
initBox()
|
||||
box?.put(foodList)
|
||||
activity?.runOnUiThread {
|
||||
batch.forEach { it.isFinish = true }
|
||||
collectionAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
},
|
||||
onError = {
|
||||
ImageUploader(totalList = foodCollectionList, uploadImage = { batch ->
|
||||
val files = batch.map { it.imageFile }
|
||||
val foodVectorList = batch.filter { it.imageVector != null }.map {
|
||||
it.imageVector!!.joinToString(
|
||||
separator = ",", prefix = "[", postfix = "]"
|
||||
)
|
||||
}
|
||||
val foodVectorJson =
|
||||
foodVectorList.joinToString(separator = ",", prefix = "[", postfix = "]")
|
||||
Timber.tag(TAG).d("json=$foodVectorJson")
|
||||
params["foodVector"] = foodVectorJson.toRequestBody()
|
||||
settingActivity?.viewModel?.uploadCollectFoodPics(files, params)
|
||||
}, onProgress = { count, batch, idList ->
|
||||
//batch.forEach {
|
||||
// it.uploadSuccess = true
|
||||
//}
|
||||
runBlocking {
|
||||
activity?.runOnUiThread {
|
||||
binding.root.postDelayed({
|
||||
settingActivity?.hideWaitingDialog()
|
||||
ToastUtils.showToast("上传失败,请稍后重试")
|
||||
}, 1000)
|
||||
settingActivity?.showWaitingDialog2("图片上传中$count/$totalFileCount")
|
||||
}
|
||||
},
|
||||
onComplete = {
|
||||
//vectorThread()
|
||||
val foodList = batch.mapIndexed { index, it ->
|
||||
Food(
|
||||
collectId = if (index < idList.size) idList[index] else null,
|
||||
foodId = checkedItem!!.foodId,
|
||||
foodName = checkedItem!!.foodName,
|
||||
foodVector = it.imageVector,
|
||||
version = GlobalData.foodModelVersion
|
||||
)
|
||||
}
|
||||
initBox()
|
||||
box?.put(foodList)
|
||||
activity?.runOnUiThread {
|
||||
batch.forEach { it.isFinish = true }
|
||||
collectionAdapter.notifyDataSetChanged()
|
||||
}
|
||||
}
|
||||
}, onError = {
|
||||
activity?.runOnUiThread {
|
||||
binding.root.postDelayed({
|
||||
settingActivity?.hideWaitingDialog()
|
||||
ToastUtils.showToast("上传成功")
|
||||
ToastUtils.showToast("上传失败,请稍后重试")
|
||||
}, 1000)
|
||||
}
|
||||
).processUploads()
|
||||
}, onComplete = {
|
||||
//vectorThread()
|
||||
binding.root.postDelayed({
|
||||
settingActivity?.hideWaitingDialog()
|
||||
ToastUtils.showToast("上传成功")
|
||||
}, 1000)
|
||||
}).processUploads()
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import java.util.concurrent.TimeUnit
|
||||
object ApiClient {
|
||||
private const val BASE_URL = "http://device.shuziweidao.com:8889/"
|
||||
|
||||
private const val TIME_OUT = 60L // 超时时间(秒)
|
||||
private const val TIME_OUT = 30L // 超时时间(秒)
|
||||
//todo 临时测试改为5秒
|
||||
// private const val TIME_OUT = 5L // 超时时间(秒)
|
||||
|
||||
|
||||
@@ -132,6 +132,7 @@ object FoodModule {
|
||||
val startTime = System.currentTimeMillis()
|
||||
val floatArray = bitmap2FloatArray(bitmap)
|
||||
Timber.tag(TAG).d("bitmap2FloatArray,耗时:${System.currentTimeMillis() - startTime}")
|
||||
|
||||
val nameScoreList = queryFoodNameScore(floatArray, queryCount)
|
||||
if (nameScoreList.isEmpty()) {
|
||||
return emptyList()
|
||||
|
||||
@@ -398,6 +398,9 @@ class MainScreenPresentation(
|
||||
* 餐品识别成功,不计费模式
|
||||
*/
|
||||
fun loadUnbilledMode() {
|
||||
if (currentUserId.isNullOrBlank()) {
|
||||
return
|
||||
}
|
||||
isLoadUnbilledMode = true
|
||||
Timber.tag(TAG).d("loadUnbilledMode")
|
||||
binding.calorieInclude.root.gone()
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package com.sw.dualscreen.utils
|
||||
import android.graphics.Bitmap
|
||||
|
||||
|
||||
object BitmapCropper {
|
||||
/**
|
||||
* 裁剪Bitmap中心区域为指定尺寸
|
||||
@@ -9,30 +10,33 @@ object BitmapCropper {
|
||||
* @param targetHeight 目标高度
|
||||
* @return 裁剪后的Bitmap
|
||||
*/
|
||||
fun cropCenter(original: Bitmap, targetWidth: Int, targetHeight: Int): Bitmap {
|
||||
fun cropCenter(original: Bitmap, targetWidth: Int, targetHeight: Int, offsetX:Int = 0, offsetY:Int = 0): Bitmap {
|
||||
val originalWidth = original.width
|
||||
val originalHeight = original.height
|
||||
|
||||
|
||||
// 计算中心点坐标
|
||||
var startX = (originalWidth - targetWidth) / 2
|
||||
var startY = (originalHeight - targetHeight) / 2
|
||||
|
||||
var startX = (originalWidth - targetWidth) / 2 + offsetX
|
||||
var startY = (originalHeight - targetHeight) / 2 + offsetY
|
||||
|
||||
// 边界检查
|
||||
startX = startX.coerceAtLeast(0)
|
||||
startY = startY.coerceAtLeast(0)
|
||||
val actualWidth = minOf(targetWidth, originalWidth - startX)
|
||||
val actualHeight = minOf(targetHeight, originalHeight - startY)
|
||||
|
||||
return Bitmap.createBitmap(original, startX, startY, actualWidth, actualHeight)
|
||||
|
||||
return Bitmap.createBitmap(original, startX, startY, actualWidth, actualHeight).also {
|
||||
// it.setConfig(Bitmap.Config.RGB_565)
|
||||
// it.density = DisplayMetrics.DENSITY_LOW
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 使用示例
|
||||
fun main() {
|
||||
// 假设这是从资源加载的Bitmap
|
||||
val originalBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888)
|
||||
|
||||
// 裁剪中心500x500区域
|
||||
val croppedBitmap = BitmapCropper.cropCenter(originalBitmap, 500, 500)
|
||||
println("裁剪后尺寸:${croppedBitmap.width}x${croppedBitmap.height}")
|
||||
}
|
||||
//fun main() {
|
||||
// // 假设这是从资源加载的Bitmap
|
||||
// val originalBitmap = Bitmap.createBitmap(1000, 1000, Bitmap.Config.ARGB_8888)
|
||||
|
||||
// // 裁剪中心500x500区域
|
||||
// val croppedBitmap = BitmapCropper.cropCenter(originalBitmap, 500, 500)
|
||||
// println("裁剪后尺寸:${croppedBitmap.width}x${croppedBitmap.height}")
|
||||
//}
|
||||
|
||||
@@ -11,7 +11,7 @@ class ImageUploader(
|
||||
private val onComplete:() -> Unit
|
||||
) {
|
||||
companion object {
|
||||
private const val BATCH_SIZE = 5
|
||||
private const val BATCH_SIZE = 3
|
||||
}
|
||||
private val uploadedCount = AtomicInteger(0)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user