缓冲区下溢?

时间:2012-11-29 19:48:06

标签: java android bufferunderflowexception

我有以下代码段。标记的行导致BufferUnderflowException。我阅读了关于异常的文档,但仍然不明白完全它是什么。我使用.rewind()方法,我在印象中缓解了这个问题。

任何人都可以请教我错误的主题或原因吗?

            Bitmap cameraBaseSized = BitmapFactory.decodeFile(cameraPath, opts);
            Bitmap canvasBlendSized = BitmapFactory.decodeFile(canvasPath, options);
            Bitmap result = cameraBaseSized.copy(Config.ARGB_8888, true);
            IntBuffer buffBase = IntBuffer.allocate(cameraBaseSized.getWidth()
                    * cameraBaseSized.getHeight());
            cameraBaseSized.copyPixelsToBuffer(buffBase);
            buffBase.rewind();
            IntBuffer buffBlend = IntBuffer.allocate(canvasBlendSized.getWidth()
                    * canvasBlendSized.getHeight());
            canvasBlendSized.copyPixelsToBuffer(buffBlend);
            buffBlend.rewind();
            IntBuffer buffOut = IntBuffer.allocate(cameraBaseSized.getWidth()
                    * cameraBaseSized.getHeight());
            buffOut.rewind();
            while (buffOut.position() < buffOut.limit()) {
                int filterInt = buffBlend.get(); //BUFFERUNDERFLOW EXCEPTION
                int srcInt = buffBase.get();
                int redValueFilter = Color.red(filterInt);
                int greenValueFilter = Color.green(filterInt);
                int blueValueFilter = Color.blue(filterInt);
                int redValueSrc = Color.red(srcInt);
                int greenValueSrc = Color.green(srcInt);
                int blueValueSrc = Color.blue(srcInt);
                int redValueFinal = multiply(redValueFilter, redValueSrc);
                int greenValueFinal = multiply(greenValueFilter, greenValueSrc);
                int blueValueFinal = multiply(blueValueFilter, blueValueSrc);
                int pixel = Color.argb(255, redValueFinal, greenValueFinal, blueValueFinal);
                buffOut.put(pixel);
            }
            buffOut.rewind();
            result.copyPixelsFromBuffer(buffOut);

异常摘录

11-29 14:41:57.347: E/AndroidRuntime(2166): Caused by: java.nio.BufferUnderflowException
11-29 14:41:57.347: E/AndroidRuntime(2166):     at java.nio.IntArrayBuffer.get(IntArrayBuffer.java:55)

我还想补充一下,这种情况只发生在特定设备上,特别是三星风味。

2 个答案:

答案 0 :(得分:3)

也许这个测试会有所帮助:

    ByteBuffer b = ByteBuffer.allocate(1);
    b.get();
    b.get();

分配后缓冲区中有1个字节,第一个get()读取此字节,缓冲区达到其限制,第二个get()是非法的,没有什么可读,所以得到BufferUnderflowException。

此代码不会失败:

    ByteBuffer b = ByteBuffer.allocate(1);
    b.get();
               b.rewind();
    b.get();

您读取了该字节,但它仍在缓冲区中,因此您可以将其倒回并再次读取该字节

答案 1 :(得分:1)

由于它在某些设备上发生,因此您可能无法获得预期的像素格式。

如果buffBlend出于任何原因短于buffOut(可能由位图为不同格式引起),当您尝试get()过去时,您会收到此异常结束了。

修改

您可以将int filterInt = buffBlend.get();更改为

int filterInt = 0;
if (buffBlend.position() < buffBlend.limit())
    filterInt = buffBlend.get();

如果你对两个缓冲区都这样做,那么应该保护你不受异常的影响,当一个图像比另一个图像大时,用黑色混合。