更新 2:
我用来缩放位图的方法。
private fun Bitmap.getResizedBitmap(maxWidth: Int, minWidth: Int, maxHeight: Int, minHeight: Int): Bitmap =
when {
width <= minWidth || height <= minHeight -> this
maxHeight > 0 && maxWidth > 0 -> {
val bitmapWidth = width
val bitmapHeight = height
val ratioBitmap = bitmapWidth.toFloat() / bitmapHeight.toFloat()
val ratioMax = maxWidth.toFloat() / maxHeight.toFloat()
var finalWidth = maxWidth.toFloat()
var finalHeight = maxHeight.toFloat()
if (ratioMax > ratioBitmap) finalWidth = maxHeight.toFloat() * ratioBitmap
else finalHeight = maxWidth.toFloat() / ratioBitmap
Bitmap.createScaledBitmap(this, finalWidth.toInt(), finalHeight.toInt(), true)
}
else -> this
}
更新 1:
override fun detectInPhoto(context: Context, uri: Uri, onLabelled: (List<Label>) -> Unit) {
try {
labelDetector.detectInImage(FirebaseVisionImage.fromFilePath(context, uri))
}catch (e: Exception){
Log.d("LabelDetector", "${e.message}")
}
堆栈跟踪:
07-24 12:59:25.566 23076-23164/com.sev7en.curator E/AndroidRuntime: FATAL EXCEPTION: ForkJoinPool.commonPool-worker-3
Process: com.sev7en.curator, PID: 23076
java.lang.OutOfMemoryError: Failed to allocate a 24140812 byte allocation with 4185968 free bytes and 18MB until OOM
at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:564)
at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:587)
at com.google.firebase.ml.vision.common.FirebaseVisionImage.getBitmapForDebugging(Unknown Source)
at com.google.firebase.ml.vision.label.FirebaseVisionLabelDetector.detectInImage(Unknown Source)
at com.sev7en.curator.ai.image.FirebasePhotoLabelDetector.detectInPhoto(FirebasePhotoLabelDetector.kt:52)
at com.sev7en.curator.util.impl.PhotoLabelManagerImpl$onUnlabelledPhotosReceived$1$2.doResume(PhotoLabelManagerImpl.kt:119)
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:42)
at kotlin.coroutines.experimental.jvm.internal.CoroutineImpl.resume(CoroutineImpl.kt:41)
at kotlinx.coroutines.experimental.DispatchedTask$DefaultImpls.run(Dispatched.kt:161)
at kotlinx.coroutines.experimental.AbstractContinuation.run(AbstractContinuation.kt:31)
at java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1388)
at java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:251)
at java.util.concurrent.ForkJoinPool$WorkQueue.runTask(ForkJoinPool.java:845)
at java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1674)
at java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1629)
at java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:108)
错误在这里:com.sev7en.curator.ai.image.FirebasePhotoLabelDetector.detectInPhoto(FirebasePhotoLabelDetector.kt:52)
。
如果我将其注释掉,则没有问题。我提供的位图也有同样的问题。
原帖
我正在使用以下方法来获取 FirebaseVisionLabelDetector:
fun getLabelDetector(options: FirebaseVisionLabelDetectorOptions?): FirebaseVisionLabelDetector =
FirebaseVision.getInstance()
.getVisionLabelDetector(options ?: getLabelDetectorOptions(0.7f))
像这样使用它:
fun getLabels(bitmap : Bitmap){
getLabelDetector.detectInImage(FirebaseVisionImage.fromBitmap(bitmap))
}
但是通过查看 Android Profiler 中的内存,我注意到为提供的位图分配了大量内存,并且它们的引用没有被删除,因此它们没有被垃圾收集。我自己没有对 Bitmap 的引用。随着每次方法调用,整体内存使用量不断增加。
我忽略了函数的结果,因为我想首先提高它的性能。