android - 缓冲区的像素不够大

标签 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);

最佳答案

我想我可能已经解决了这个问题——看看 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/

相关文章:

java - 将字节数组写入文件(大文件大小)

java - 如何在 Android 中从 Fragment 调用 ArrayAdapter 构造函数

java - TYPE_TEXT_VARIATION_VISIBLE_PASSWORD 适用于使用 Phonegap 的 Android

android - 使用混淆器混淆后,CardView 阴影未出现在 Lollipop 中

javascript - 设置 HTML Canvas 2D 上下文的 X 和 Y(屏幕抖动)

Android - 位图 tileMode ="repeat"无法正常工作

android - java.lang.OutOfMemoryError on line httpPost.setEntity(new UrlEncodedFormEntity(params)) 在 android 中以字符串格式发送图像时

android - 需要算法建议 : What's the best way to sort TV show episodes?

javascript - 从 PDF.JS pdf 转换为 Canvas 标签获取 base64 png?

javascript - HTML5 Canvas 上的drawImage 出现奇怪的错误