Android ImageReader.acquireLatestImage returns invalid JPG

前端 未结 6 908
悲&欢浪女
悲&欢浪女 2020-12-01 13:21

I am using Android ImageReader class to receive Bitmaps from MediaProjection.createVirtualDisplay method.

My code so far looks like this:

mProjectio         


        
6条回答
  •  长情又很酷
    2020-12-01 13:56

    I encountered exactly your problem. My ImageReader created as so:

    ImageReader.newInstance(mCaptureSize.getWidth(), mCaptureSize.getHeight(), ImageFormat.JPEG, 1);
    

    The ImageReader above should only return compressed images, and these need to be decompressed. I acquireLatestImage(), then pass it through the following:

    ByteBuffer bBuffer = planes[0].getBuffer;
    bBuffer.rewind();
    byte[] buffer = new byte[bBuffer.remaining()];
    planes[0].getBuffer().get(buffer);
    Bitmap bitmap = BitmapFactory.decodeByteArray(buffer, 0, buffer.length);
    

    The key for me was to rewind the ByteBuffer. Your code should work as so:

    mProjection.createVirtualDisplay("test", width, height, density, flags, mImageReader.getSurface(), new VirtualDisplayCallback(), mHandler);
                mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                    @Override
                    public void onImageAvailable(ImageReader reader) {
                        Image image = null;
                        try {
                            image = mImageReader.acquireLatestImage();
                            final Image.Plane[] planes = image.getPlanes();
                            final ByteBuffer buffer = planes[0].getBuffer();
                            buffer.rewind()
                            final byte[] data = new byte[buffer.capacity()];
                            buffer.get(data);
                            final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
                            if (bitmap==null)
                                Log.e(TAG, "bitmap is null");
    
                        } catch (Exception e) {
                            if (image!=null)
                                image.close();
                        }
                    }
    
                }, mHandler);
    

    I don't like having to copy the ByteBuffer through an intermediate byte[], but the internal array is protected.

    Tested working on 5.0.1 on an HTC

提交回复
热议问题