我得到的错误是我的缓冲区不够大以容纳像素。有什么建议吗?位图 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);
最佳答案
我想我可能已经解决了这个问题——看看 Bitmap::copyPixelsFromBuffer() 的源代码(版本 2.3.4_r1,最后一次在 Grepcode 上更新 4.4 之前的位图)。
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() 方法来计算缓冲区的容量,该方法考虑了其位置属性的当前值。如果您在调用 copyPixelsFromBuffer() 之前对缓冲区调用 rewind(),您应该会看到运行时异常消失。
关于android - 缓冲区的像素不够大,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12208619/