如何在方向更改时使用MediaProjection处理图像捕获



我编写了一个测试应用程序,用于使用MediaProjection类捕获图像。

imageReader = ImageReader.newInstance(currentWidth, currentHeight, PixelFormat.RGBA_8888, 2);
imageReader.setOnImageAvailableListener(this, null);
virtualDisplay = mediaProjection.createVirtualDisplay("captureDisplay",
                    currentWidth, currentHeight,  DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |
                            DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC| 
                            DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR |
                            DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE |
                          DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, Screen.getDensity(mContext),                          imageReader.getSurface(), null, null);

//DisplayManager标志是仅跟踪

在CCD_ 1方法中

我试着得到如下图像:

Bitmap bitmap;
Image mImage = null;
try {
mImage = mImageReader .acquireLatestImage();
if (img != null) {
    final Image.Plane[] planes = mImage.getPlanes();
    final ByteBuffer buffer = planes[0].getBuffer();
    int pixelStride = planes[0].getPixelStride();
    int rowStride = planes[0].getRowStride();
    int rowPadding = rowStride - pixelStride * mImage.getWidth();
    bitmap = Bitmap.createBitmap(mImage.getWidth() + rowPadding/pixelStride, mImage.getHeight(), Bitmap.Config.ARGB_8888);  
    bitmap.copyPixelsFromBuffer(buffer);
    ByteArrayOutputStream stream = new ByteArrayOutputStream();
    bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
   byte[] rawData = lastImageAcquiredRaw = stream.toByteArray();
   if (rawData != null) {
    Bitmap fullScreen = BitmapFactory.decodeByteArray(rawData, 0, rawData.length);
    savebitmap(fullScreen,"image",i); //Saving bitmap in storage
    }
}

到目前为止,我还可以,当我的应用程序处于横向时,我得到了正确的图像。面临的问题是方向的改变,我没有得到正确的图像。有些时候再换回风景也拍不好。

我学习了ImageReader.java类。并没有提到需要处理方向变化。

尝试使用acquireNextImageNoThrowISE(),acquireNext Images(),但没有使用。

有没有人尝试过或有可能在方位上获得正确的图像?

请帮我树立正确的形象。

我知道这篇文章有点过时了,但最近几天我也被同样的事情扼杀了。我也在使用MediaProjection API,VirtualDisplay和ImageReader的表面。我要展示的解决方案并不是100%完全证明,所以如果有人有任何有用的建议,我们将非常欢迎。

第一步:创建虚拟显示器后添加OrientationChangeCallback

OrientationChangeCallback orientationChangeCallback = new OrientationChangeCallback(context);
if (orientationChangeCallback.canDetectOrientation()) {
  orientationChangeCallback.enable();
}

第二步:定义定向回调,它本质上重新启动捕获

private class OrientationChangeCallback extends OrientationEventListener {
        OrientationChangeCallback(Context context) {
            super(context);
        }
        @Override
        public void onOrientationChanged(int orientation) {
            final int rotation = mDisplay.getRotation();
            if(rotation != mRotation) {
                mRotation = rotation;
                if (mVirtualDisplay != null) {
                    mVirtualDisplay.release();
                }
                if (mImageReader != null) {
                    mImageReader.setOnImageAvailableListener(null, null);
                }
                if (!mProjectionStopped) {
                    createVirtualDisplay();
                }
            }
        }
    }

请注意,我持有对ImageReader和VirtualDisplay的引用,并且还有一个volatile boolean mRotation来检查屏幕是否真的旋转了。

我遇到的问题是,在一些设备(包括Nexus 5X)上,图像在X次或旋转(通常为10-20次)后可能会损坏。如果我再旋转一次设备,图像就会被正确捕获。在快速设备(谷歌像素)上,我无法复制损坏的图像问题,所以我猜测这可能是同步问题。

相关内容

  • 没有找到相关文章

最新更新