Java如何将java.nio.Buffer转换为ByteBuffer

6

我遇到了一个小问题,我有两个库,一个将输出作为java.nio.Buffer发送给我,另一个将输入作为java.nio.ByteBuffer接收,我该如何进行转换?

谢谢。

这个Buffer是来自javaCV的代码:

private BytePointer[]   image_ptr;
private Buffer[]        image_buf;

// Determine required buffer size and allocate buffer
int size = avpicture_get_size(fmt, width, height);
image_ptr = new BytePointer[] { new BytePointer(av_malloc(size)).capacity(size) };
image_buf = new Buffer[] { image_ptr[0].asBuffer() };

// Assign appropriate parts of buffer to image planes in picture_rgb
// Note that picture_rgb is an AVFrame, but AVFrame is a superset of AVPicture
avpicture_fill(new AVPicture(picture_rgb), image_ptr[0], fmt, width, height);
picture_rgb.format(fmt);
picture_rgb.width(width);
picture_rgb.height(height);

1
java.nio.Buffer是一个抽象类。结果的实际类型是什么?它会变化吗?它包含什么? - Kayaman
1
请参考链接中的问题 - 您可以分配一个新的 ByteBuffer 并调用 asXxxBuffer().put(...) 来填充它,具体取决于您的 Buffer 的实际类型(因此您需要测试它们所有)。 - Tunaki
1
@Edward 不,这不是浪费时间!你可以将其发布在链接的问题上,它们是相同的:将 Buffer 的实例转换为 ByteBuffer。那里的答案确实可以改进。 - Tunaki
1
@EdwinDalorzo 不,答案可能会更好...但由于问题实际上是相同的,将其集中在一个地方更好。 - Tunaki
1
@EdwinDalorzo 这些问题完全相同。这是更新相关问题的最佳机会,以添加其他答案。目标不是在多个地方拥有信息,而是有一个涵盖该主题的问题,从而完整覆盖它。这样可以增强问题的价值,使其成为规范问题。 - Tunaki
显示剩余7条评论
1个回答

2
首先,由于Buffer是一个抽象类,而ByteBuffer是它的其中一个子类,所以你从第一个库中得到的输出很可能实际上是一个ByteBuffer。如果可能的话,请检查库返回的Buffer实现,因为如果它实际上返回的是ByteBuffer,你可以将输出强制转换为ByteBuffer并完成操作。
如果你不知道库返回的是哪个Buffer实现,那么你就需要使用 instanceof 测试来确定它是哪个子类,并在将其转换为子类后将数据从返回的Buffer复制到新的ByteBuffer中。这是因为Buffer接口实际上并没有提供任何方法来读取缓冲区中的数据;只有各个子类(ByteBuffer、ShortBuffer、LongBuffer等)才提供这些方法。幸运的是,Buffer只有7个可能的子类,每个子类对应一种原始类型。
一旦确定了你拥有哪个Buffer子类,你就可以使用“asXXXBuffer()”方法将数据复制到一个ByteBuffer中,具体方法可以参考这个答案,正如@Tunaki所指出的那样。
代码看起来像这样:
Buffer outputBuffer = library.getBuffer();
ByteBuffer byteBuffer;
if (outputBuffer instanceof ByteBuffer) {
    byteBuffer = (ByteBuffer) outputBuffer;
} else if (outputBuffer instanceof CharBuffer) {
    byteBuffer = ByteBuffer.allocate(outputBuffer.capacity());
    byteBuffer.asCharBuffer().put((CharBuffer) outputBuffer);
} else if (outputBuffer instanceof ShortBuffer) {
    byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * 2);
    byteBuffer.asShortBuffer().put((ShortBuffer) outputBuffer);
} else if (outputBuffer instanceof IntBuffer) {
    byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * 4);
    byteBuffer.asIntBuffer().put((IntBuffer) outputBuffer);
} else if (outputBuffer instanceof LongBuffer) {
    byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * 8);
    byteBuffer.asLongBuffer().put((LongBuffer) outputBuffer);
} else if (outputBuffer instanceof FloatBuffer) {
    byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * 4);
    byteBuffer.asFloatBuffer().put((FloatBuffer) outputBuffer);
} else if (outputBuffer instanceof DoubleBuffer) {
    byteBuffer = ByteBuffer.allocate(outputBuffer.capacity() * 8);
    byteBuffer.asDoubleBuffer().put((DoubleBuffer) outputBuffer);
} 

请注意,您分配的ByteBuffer的大小取决于您从哪个Buffer子类复制,因为不同的原始类型使用不同数量的字节存储。例如,由于int是4个字节,如果您的库提供了IntBuffer,则需要分配4倍容量的ByteBuffer。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接