【问题标题】:Can I create Bitmaps with the Android NDK in C++ and pass them to Java really fast?我可以使用 C++ 中的 Android NDK 创建位图并将它们快速传递给 Java 吗?
【发布时间】:2011-12-17 13:35:43
【问题描述】:

我需要使用 ndk 在 C++ 中创建位图并将它们传递给 Java。我的意思不是复制,而是实际上将它们作为参数或返回值或其他类似的东西传递,因为复制它们太慢了。我还真的需要在 NDK 部分而不是在 java 中创建它们。

有人知道怎么做吗?

【问题讨论】:

    标签: java android c++ bitmap


    【解决方案1】:

    正如 Peter Lawrey 已经指出的那样,使用非 Java 对象是不可能的,但是可以直接从简单的 Java 字节数组(可以在 C++ 端直接访问)绘制原始数据。

    最后,您甚至可以使用此字节数组调用Canvas.drawBitmap(..) 来绘制您创建的图像。当然,这需要将图像直接以字节数组中所需的格式存储在 C++ 端。

    Java:

    byte[] pixelBuf = new byte[bufSize];
    

    然后将byte[] 引用传递给本机C++ 实现。在 C++ 方面,您可以调用

    C++:

    jbyte* pixelBufPtr = env->GetByteArrayElements(pixelBuf, JNI_FALSE);
    jsize pixelBufLen = env->GetArrayLength(env, pixelBuf);
    // modify the data at pixelBufPtr with C++ functions
    env->ReleaseByteArrayElements(pixelBuf, pixelBufPtr, 0);
    

    【讨论】:

    • 感谢您的回复。我是否理解正确,字节数组必须完全在 java 中创建,然后只能在 c++ 中访问和更改?
    • 是的,您必须在 Java 中创建字节数组。在 C++ 端,您可以“锁定”数据以获取指针。解锁后,您也可以在 Java 中使用和更改它。请参阅我的更新答案。
    【解决方案2】:

    您可以尝试使用直接的 ByteBuffer。 ByteBuffer 指的是内存的本机区域。但是,要在 Java 中使用 Image,它必须位于 Java 对象中。您可以在 Java 或 C 中组装此对象,但我看不出如何避免复制图像,除非您的 C 库将图像写入 Java 结构。

    【讨论】:

    • 感谢您的回复。我的目标是在 Java 堆内存之外分配位图,这意味着它必须在 C++ 中分配。有没有办法通过字节缓冲区以某种方式实现这一点?
    • 您可以将 ByteBuffer 的地址字段更改为从 JNI(或反射)指向您喜欢的位置
    • 再次感谢,我会试试这个!
    【解决方案3】:

    我遇到了同样的问题,我的解决方案是在 C++ 中分配巨大的缓冲区,然后将每个请求的“视图”绘制到 Java 位图中。我使用 Android 2.2 中出现的“新”NDK 位图功能;它们允许直接访问位图位。它可能不适合您的使用,但它确实避免了复制位图并允许您创建与可用内存一样大的位图。我创建了一个显示窗口大小的位图,然后使用我自己的本机代码缩放器从大位图中绘制缩放视图。

    【讨论】:

    • BitBank:您是否从在线示例中获得了位图绘制代码?如果是这样,你能发布一个链接吗?
    • 位图绘制代码是我自己的(ARM asm),我宁愿不贴。
    猜你喜欢
    • 2015-10-26
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-12-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多