java.lang.UnsupportedOperationException 在 java.nio.ByteBuffer.arrayOffset?
java.lang.UnsupportedOperationException at java.nio.ByteBuffer.arrayOffset?
我需要从 IFrameCallback 获取位图,它的作用是处理 frame来自 UVCCamera 预览,但有一个例外:
java.lang.UnsupportedOperationException at
java.nio.ByteBuffer.arrayOffset
private final IFrameCallback callback = new IFrameCallback() {
@override
public void onFrame(final ByteBuffer frame) {
new Thread(new Runnable() {
byte[] bytes = new byte[frame.remaining()];
frame.get(bytes);
if(bytes.length > 0) {
int offset = frame.arrayOffset();
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, offset, bytes.length - offset);
......
}
}).start();
}
}
或者如果我使用 createBitmap 而不是 decodeByteArray,我得到这个异常:
java.lang.RuntimeException: Buffer not large enough for pixels at
android.graphics.Bitmap.copyPixelsFromBuffer
private final IFrameCallback callback = new IFrameCallback() {
@override
public void onFrame(final ByteBuffer frame) {
new Thread(new Runnable() {
Bitmap bitmap = Bitmap.createBitmap(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(frame);
......
}).start();
}
}
因为预览尺寸是1280 x 720,所以RuntimeException的问题可以忽略。
关于从 ByteBuffer 获取 arrayOffset 的第一个异常有什么想法吗?
PS: 我知道
UnsupportedOperationException - If this buffer is not backed by an
accessible array
我的观点是:是否有任何其他方法可以获取 arrayOffset,或者如果不能这样做以及如何解决运行时异常?
嗯,既然没有好的解决办法,我就改了从IFrameCallback获取位图的方式.
因为我已经将 UVCCamera.PIXEL_FORMAT_NV21 格式应用于 UVCCamera:
uvcCamera.setFrameCallback(frameCallback,
UVCCamera.PIXEL_FORMAT_NV21);
所以,我可以得到 bitmap 只需转换 YuvImage:
private ChannelBufferOutputStream stream = new ChannelBufferOutputStream(MessageBuffers.dynamicBuffer());
......
private final IFrameCallback callback = new IFrameCallback() {
@override
public void onFrame(final ByteBuffer frame) {
new Thread(new Runnable() {
@override
public void run() {
byte[] bytes = new byte[frame.remaining()];
frame.get(bytes);
if(bytes.length > 0) {
YuvImage yuvImage = new YuvImage(bytes, ImageFormat.NV21, UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, null);
bytes = null;
if(yuvImage.getYuvData().length > 0) {
yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 80, stream);
Bitmap bitmap = BitmapFactory.decodeByteArray(stream.buffer().array(), 0, stream.buffer().array().length);
......
}
}
}
}).start();
}
}
我需要从 IFrameCallback 获取位图,它的作用是处理 frame来自 UVCCamera 预览,但有一个例外:
java.lang.UnsupportedOperationException at java.nio.ByteBuffer.arrayOffset
private final IFrameCallback callback = new IFrameCallback() {
@override
public void onFrame(final ByteBuffer frame) {
new Thread(new Runnable() {
byte[] bytes = new byte[frame.remaining()];
frame.get(bytes);
if(bytes.length > 0) {
int offset = frame.arrayOffset();
Bitmap bitmap = BitmapFactory.decodeByteArray(bytes, offset, bytes.length - offset);
......
}
}).start();
}
}
或者如果我使用 createBitmap 而不是 decodeByteArray,我得到这个异常:
java.lang.RuntimeException: Buffer not large enough for pixels at android.graphics.Bitmap.copyPixelsFromBuffer
private final IFrameCallback callback = new IFrameCallback() {
@override
public void onFrame(final ByteBuffer frame) {
new Thread(new Runnable() {
Bitmap bitmap = Bitmap.createBitmap(UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(frame);
......
}).start();
}
}
因为预览尺寸是1280 x 720,所以RuntimeException的问题可以忽略。
关于从 ByteBuffer 获取 arrayOffset 的第一个异常有什么想法吗?
PS: 我知道
UnsupportedOperationException - If this buffer is not backed by an accessible array
我的观点是:是否有任何其他方法可以获取 arrayOffset,或者如果不能这样做以及如何解决运行时异常?
嗯,既然没有好的解决办法,我就改了从IFrameCallback获取位图的方式.
因为我已经将 UVCCamera.PIXEL_FORMAT_NV21 格式应用于 UVCCamera:
uvcCamera.setFrameCallback(frameCallback, UVCCamera.PIXEL_FORMAT_NV21);
所以,我可以得到 bitmap 只需转换 YuvImage:
private ChannelBufferOutputStream stream = new ChannelBufferOutputStream(MessageBuffers.dynamicBuffer());
......
private final IFrameCallback callback = new IFrameCallback() {
@override
public void onFrame(final ByteBuffer frame) {
new Thread(new Runnable() {
@override
public void run() {
byte[] bytes = new byte[frame.remaining()];
frame.get(bytes);
if(bytes.length > 0) {
YuvImage yuvImage = new YuvImage(bytes, ImageFormat.NV21, UVCCamera.DEFAULT_PREVIEW_WIDTH, UVCCamera.DEFAULT_PREVIEW_HEIGHT, null);
bytes = null;
if(yuvImage.getYuvData().length > 0) {
yuvImage.compressToJpeg(new Rect(0, 0, yuvImage.getWidth(), yuvImage.getHeight()), 80, stream);
Bitmap bitmap = BitmapFactory.decodeByteArray(stream.buffer().array(), 0, stream.buffer().array().length);
......
}
}
}
}).start();
}
}