Android MediaProjection - какое разрешение подходит для VirtualDisplay и ImageReader?

Я использовал MediaProjection api вместе с VirtualDisplay и ImageReader для совместного использования экрана. Вот метод создания VirtualDisplay и ImageReader:

      private void createVirtualDisplay(Activity mContext) {


        final DisplayMetrics metrics = new DisplayMetrics();
        mContext.getWindowManager().getDefaultDisplay().getRealMetrics(metrics);

        final int width = metrics.widthPixels;
        final int height = metrics.heightPixels;
        final int densityDpi = metrics.densityDpi;
        final int MAX_IMAGES = 2;

        mWidth = width; // 1080
        mHeight = height; // 2400
        mDensity = densityDpi;

        Log.d(TAG," >>> Creating display metric w: " + mWidth + " h: " + mHeight + " dens: " + mDensity);

        mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, MAX_IMAGES);
        mVirtualDisplay = mMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight,
                mDensity, getVirtualDisplayFlags(), mImageReader.getSurface(), null, mHandler);
        mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);

        mCallback.onReceivedDisplayInfo(mWidth, mHeight);

    }

И необработанные байты rgba принимаются OnimageAvailable:

       private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {
        @Override
        public void onImageAvailable(ImageReader reader) {

            try (Image image = mImageReader.acquireLatestImage()) {
                if (image != null) {
                    publishFrame(image);
                }

            } catch (Exception e) {
                e.printStackTrace();
                mCallback.onError(e.getMessage());
            }
        }
    }
      private void publishFrame(Image image) {

        int mWidth = image.getWidth(); 
        int mHeight = image.getHeight(); 

        // Four bytes per pixel: width * height * 4.
        byte[] rgbaBytes = new byte[mWidth * mHeight * 4];
        // put the data into the rgbaBytes array.
        image.getPlanes()[0].getBuffer().get(rgbaBytes);

        image.close();

        if (mCallback != null) {
            mCallback.onScreenFrameCaptured(rgbaBytes);
        }
    }

Пока все хорошо, и кадры отображаются на поверхности без проблем. Но тут все становится интересно:

После изменения ширины и высоты на 640 x 480 результат немного лучше:

но, как видите, что-то не так с соотношением сторон общего экрана. Наконец, когда я изменяю ширину и высоту на 768 * 1366, результат несколько приемлем, но

  1. Почему, когда я устанавливаю ширину и высоту экрана устройства для Image ريال eader и VirtualDisplay, общий экран повреждается? (для этого устройства: ширина =1080 высота =2400)

  2. Почему, когда я устанавливаю высоту больше ширины, общий экран хорош?

  3. На последнем изображении общий экран не покрывает весь целевой SurfaceView. Как я могу установить разрешение для VirtualDisplay и ImageReader, которое охватывает весь SurfaceView?

0 ответов

Другие вопросы по тегам