【问题标题】:Does the resulting image from using ImageIO.read() still use the same memory passed to it?使用 ImageIO.read() 生成的图像是否仍使用传递给它的相同内存?
【发布时间】:2020-07-02 07:01:54
【问题描述】:

我正在开发一个 OpenGL 项目,该项目需要我通过 JNI 库实现 JVM,以使用 JavaGraphics2D 渲染到 c++ 中的 OpenGL 映射缓冲区。我知道我可以使用指向映射缓冲区的void* 指针创建一个java.nio.ByteBuffer 对象:

jobject NewDirectByteBuffer(JNIEnv* env, void* address, jlong capacity);

如果我通过将 ByteBuffer 转换为 byte[] 数组,将该数组包裹在 ByteArrayInputStream 周围并使用 ImageIO.read() 来传递它,那么最终 BufferedImage 仍将使用与void* 存储指针或 ImageIO 方法是否为 BufferedImage 存储分配新内存?即如果我使用 Java2DGraphics 绘制到 BufferedImage 上,是否会导致原始 void* 内存也被更改?

如果不是这样,我将不得不将 BufferedImage 数据复制到 ByteBuffer 中

【问题讨论】:

    标签: java c++ java-native-interface bufferedimage bytebuffer


    【解决方案1】:

    ImageIO.read 处理各种输入源并分配自己的内存,它不与它返回的 BufferedImage 共享您的原始 byte[]。

    所以你需要调用 ImageIO.write 来取回修改。

    【讨论】:

    • 是否有另一个我可以使用的类/库可以做到这一点?
    • 我怀疑你会找到一些东西 - 如果存储扩展也会有问题。几乎所有的图像阅读器都会从某种形式的InputStream 中读取它们的源,并且不知道底层存储格式可能是 ByteBuffer、byte[]、文件/路径、ZIP/压缩、HTTP 连接。让ImageIO.write 保存到新的ByteArrayOutputStream 应该不难,然后将缓冲区复制回来。
    • @fsxflyer789Productions 您的原始内存已经与您从它创建的byte[] 数组分离。然后,您将数组包装在 ByteArrayInputStream 中,其读取操作原则上是将数据复制到目标存储中。除了生成的BufferedImage 的存储不可能连接到您的原始内存之外,当图像被修改时,您实际上期望什么?每次更新时要以原始图像格式重新编码的数据?图像解码根本不一定是可逆的过程。
    • @Holger 由于原始内存缓冲区连接到纹理,因此在 java 中对缓冲区所做的任何更改以反映原始内存本身的更改
    • @fsxflyer789Productions 当您使用ImageIO 时,这意味着源以特定的图像格式编码,png、jpeg、gif 等等。因此,您希望每当您更改BufferedImage 中的单个像素时,整个图像都会重新编码到源缓冲区?除了这个想法的疯狂开销之外,如果新编码的图片不适合原始缓冲区怎么办?压缩数据的大小取决于实际内容。
    猜你喜欢
    • 1970-01-01
    • 2021-05-07
    • 2022-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-05-17
    • 2020-02-18
    • 2011-11-03
    相关资源
    最近更新 更多