【发布时间】:2019-04-19 09:35:59
【问题描述】:
我正在尝试将从资源获取的图像转换为 ByteArray 稍后将通过 Socket 发送。我一直在测量每次转换的时间。
我在 Flutter 和原生 Android (Kotlin) 上都做过。所有测试都是在大约 1-2MB 的同一图像上完成的。
颤振代码:
sendMessage() async {
if (socket != null) {
Stopwatch start = Stopwatch()..start();
final imageBytes = await rootBundle.load('assets/images/stars.jpg');
final image = base64Encode(imageBytes.buffer.asUint8List(imageBytes.offsetInBytes, imageBytes.lengthInBytes));
print('Converting took ${start.elapsedMilliseconds}');
socket.emit("message", [image]);
}
}
Kotlin 代码:
private fun sendMessage() {
var message = ""
val thread = Thread(Runnable {
val start = SystemClock.elapsedRealtime()
val bitmap = BitmapFactory.decodeResource(resources, R.drawable.stars)
message = Base64.encodeToString(getBytesFromBitmap(bitmap), Base64.DEFAULT)
Log.d("Tag", "Converting time was : ${SystemClock.elapsedRealtime() - start}")
})
thread.start()
thread.join()
socket.emit("message", message)
}
private fun getBytesFromBitmap(bitmap: Bitmap): ByteArray? {
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
return stream.toByteArray()
}
我实际上一直期望原生代码比 Flutter 快得多,但事实并非如此。Flutter 的转换大约需要 50 毫秒,而原生代码大约需要 2000-3000 毫秒。 我认为线程可能是这种情况,所以我尝试在后台线程上运行本机代码的转换,但它没有帮助。 你能告诉我为什么会有如此不同的时间,以及如何在本机代码中更好地实现它吗?有没有办法省略投射到位图等?也许这让它变得如此之长。
编辑。添加 getBytesFromBitmap 函数
【问题讨论】:
-
尝试
BitmapFactory而不是getDrawable()- 但我不希望有太大的不同 -
现在我可能是错的,但我认为当你“使用原生 Android”时实际上会发生很多事情:它会查看所有资源以找到你想要的资源,找到它的位置并加载到一个字节数组,它从该字节数组构建一个位图,将该位图打包成一个可绘制对象,然后再次提取它,可能在此过程中左右复制,然后将其转换回缓冲区,可能会在此过程中损失一些质量取决于默认的位图编码是什么。即便如此,2mb 图像的 3000 毫秒也是很多。不应该花这么长时间。我确定有办法加载
-
@pskink 它没有改变任何东西:(
-
不同的是,在颤振中你只是读取你的数据而没有任何image解码,而在kotlin中你首先解码为
Bitmap然后你将它压缩回来 -
尝试
Resources#openRawResource()并在循环中读取它的InputStream
标签: android flutter bitmap drawable