缓冲区不足以容纳像素

时间:2012-08-31 03:44:43

标签: android canvas bitmap

我得到的错误是我的缓冲区不足以容纳像素。有什么建议?位图b的大小应该与我试图将其像素放入的gSaveBitmap相同。

if(gBuffer == null)
        {
            Bitmap b = Bitmap.createScaledBitmap(gBitmap, mWidth, mHeight, false);
            //gBuffer = ByteBuffer.allocateDirect(b.getRowBytes()*b.getHeight()*4);
            ByteArrayOutputStream stream = new ByteArrayOutputStream();
            b.compress(Bitmap.CompressFormat.PNG,  100,  stream);
            gBuffer = ByteBuffer.wrap(stream.toByteArray());
            b.recycle();
        }
        gSaveBitmap.copyPixelsFromBuffer(gBuffer);

更新:以下代码提供完全相同的错误,不涉及任何压缩。

if(gBuffer == null)
        {
            Bitmap b = Bitmap.createScaledBitmap(gBitmap, mWidth, mHeight, false);

            int bytes = b.getWidth()*b.getHeight()*4;
            gBuffer = ByteBuffer.allocate(bytes);
            b.copyPixelsToBuffer(gBuffer);              
            b.recycle();
        }
        gSaveBitmap.copyPixelsFromBuffer(gBuffer);

更新:通过将gBuffer的大小加倍来解决问题。也许有人可以告诉我为什么这是正确的大小。另外......图片旋转错误,需要旋转90度。有关如何在gBuffer中重新排列数据的想法吗?

gBuffer = ByteBuffer.allocate(b.getRowBytes()*b.getHeight()*2);

2 个答案:

答案 0 :(得分:1)

我想我可能已经解决了这个问题 - 看看源代码(版本2.3.4_r1,最后一次Bitmap在4.4之前的Grepcode上更新)Bitmap::copyPixelsFromBuffer()

public void copyPixelsFromBuffer(Buffer src) {

     checkRecycled("copyPixelsFromBuffer called on recycled bitmap");

     int elements = src.remaining();
     int shift;
     if (src instanceof ByteBuffer) {

         shift = 0;

     } else if (src instanceof ShortBuffer) {
         shift = 1;

     } else if (src instanceof IntBuffer) {
         shift = 2;

     } else {

         throw new RuntimeException("unsupported Buffer subclass");

     }

     long bufferBytes = (long)elements << shift;
     long bitmapBytes = (long)getRowBytes() * getHeight();

     if (bufferBytes < bitmapBytes) {

         throw new RuntimeException("Buffer not large enough for pixels");

     }

     nativeCopyPixelsFromBuffer(mNativeBitmap, src);

 }

错误的措辞有点不清楚,但代码澄清了 - 这意味着您的缓冲区计算为没有足够的数据来填充位图的像素。 这是因为它们使用缓冲区的remaining()方法来计算缓冲区的容量,该方法考虑了其position属性的当前值。如果在调用copyPixelsFromBuffer()之前在缓冲区上调用rewind(),则应该看到运行时异常消失。

答案 1 :(得分:0)

我找到了这个问题的答案:

您应始终设置buffer size > bit map size,因为不同Android版本上的位图始终更改。

您可以在下面记录代码以查看buffer size & bitmap size(Android API应&gt; = 12以使用以下日志)

Log.i("", "Bitmap size = " + mBitmap.getByteCount());
        Log.i("", "Buffer size = " + mBuffer.capacity());

应该有效。

谢谢,