Tag: graphicsmagick

JNI – 在Java和Native代码之间传递大量数据

我想要实现以下目标: 1)我在java端有一个表示图像的字节数组。 2)我需要让我的本机代码访问它。 3)本机代码使用GraphicsMagick解码此图像,并通过调用resize创建一堆缩略图。 它还计算图像的感知散列,该散列是矢量或unint8_t数组。 4)一旦我将这些数据返回给Java端,不同的线程将读取它。 缩略图将通过HTTP上传到某些外部存储服务。 我的问题是: 1)将字节从Java传递到本机代码的最有效方法是什么? 我可以将其作为字节数组访问。 我认为将其作为字节缓冲区(包装此字节数组)与字节数组传递在此处没有任何特别的优势。 2)将这些缩略图和感知哈希返回给java代码的最佳方法是什么? 我想到了几个选择: (i)我可以在Java中分配一个字节缓冲区,然后将其传递给我的本机方法。 然后,本机方法可以写入它并在完成后设置一个限制并返回写入的字节数或一些表示成功的布尔值。 然后,我可以对字节缓冲区进行切片和切块,以提取不同的缩略图和感知哈希,并将其传递给将上传缩略图的不同线程。 这种方法的问题是我不知道要分配的大小。 所需的大小将取决于我提前生成的缩略图的大小和缩略图的数量(我事先知道)。 (ii)一旦我知道所需的大小,我也可以在本机代码中分配字节缓冲区。 我可以根据我的自定义打包协议将我的blob记忆到正确的区域并返回此字节缓冲区。 (i)和(ii)都很复杂,因为自定义打包协议必须指示每个缩略图的长度和感知散列。 (iii)定义具有缩略图字段的Java类:字节缓冲区数组和感知散列:字节数组。 当我知道所需的确切大小时,我可以在本机代码中分配字节缓冲区。 然后我可以将GraphicsMagick blob中的字节memcpy到每个字节缓冲区的直接地址。 我假设还有一些方法来设置写在字节缓冲区上的字节数,以便java代码知道字节缓冲区有多大。 设置字节缓冲区后,我可以填写我的Java对象并返回它。 与(i)和(ii)相比,我在这里创建了更多的字节缓冲区以及Java对象,但我避免了自定义协议的复杂性。 (i),(ii)和(iii)背后的基本原理 – 鉴于我对这些缩略图的唯一做法是上传它们,我希望通过NIO上传它们时保存带字节缓冲区(vs字节数组)的额外副本。 (iv)定义一个Java类,它具有缩略图的字节数组(而不是字节缓冲区)和感知散列的字节数组。 我在我的本机代码中创建这些Java数组,并使用SetByteArrayRegion从我的GraphicsMagick blob复制字节。 与以前的方法相比,缺点是,在上传时,将此字节数组从堆中复制到某个直接缓冲区时,Java域中还会有另一个副本。 不确定我是否会在复杂性方面保存任何东西,而不是(iii)。 任何建议都很棒。 编辑:@main提出了一个有趣的解决方案。 我正在编辑我的问题以跟进该选项。 如果我想像@main建议的那样在DirectBuffer中包装本机内存,我怎么知道何时可以安全地释放本机内存?