我得到的错误是我的缓冲区不足以容纳像素。有什么建议?位图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);
答案 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());
应该有效。
谢谢,