【问题标题】:Flutters resource load faster than native AndroidFlutters 资源加载速度比原生 Android 快
【发布时间】: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


【解决方案1】:

您看到的不同之处在于,在颤振代码中,您只需读取数据而无需任何图像解码,而在 kotlin 中,您首先解码为 Bitmap,然后您将 compress() 将其返回 - 如果您想加快速度up 只需通过调用Resources#openRawResource 获取InputStream 并无需任何解码即可读取您的图像资源

【讨论】:

    【解决方案2】:

    这与您将其转换为字节的方式有关...您能否发布您的 getBytesFromBitmap 函数?另外,本机代码的转换确实应该在后台线程中完成,请在这种情况下上传您的结果。

    【讨论】:

    • 是的,抱歉,已更改帖子
    猜你喜欢
    • 2018-03-12
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-05-05
    • 1970-01-01
    相关资源
    最近更新 更多