Подтвердить что ты не робот

Скриншот андроидной медиафотографии содержит черную рамку

Я работаю над записью своего экрана с помощью MediaProjection следующим образом

Display display = getWindowManager().getDefaultDisplay();
Point size = new Point();
display.getSize(size);
displayWidth = size.x;
displayHeight = size.y;

imageReader = ImageReader.newInstance(displayWidth, displayHeight, ImageFormat.JPEG, 5);

int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;

DisplayMetrics metrics = getResources().getDisplayMetrics();
int density = metrics.densityDpi;

mediaProjection.createVirtualDisplay("test", displayWidth, displayHeight, density, flags, 
      imageReader.getSurface(), null, projectionHandler);

Image image = imageReader.acquireLatestImage();
byte[] data = getDataFromImage(image);
Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);

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

введите описание изображения здесь

ИЗМЕНИТЬ

Вышеупомянутая проблема может быть решена с помощью растровых операций.

Однако теперь я ищу решение, которое можно применить к MediaProjection или SurfaceView для ImageReader для реализации записи устройства.

4b9b3361

Ответ 1

Если у вас нет контроля над изображением самостоятельно, вы можете изменить его, сделав что-то вроде этого, предполагая, что ваш Bitmap называется изображением.

Bitmap imageWithBG = Bitmap.createBitmap(image.getWidth(), image.getHeight(),image.getConfig());  // Create another image the same size
imageWithBG.eraseColor(Color.BLACK);  // set its background to white, or whatever color you want
Canvas canvas = new Canvas(imageWithBG);  // create a canvas to draw on the new image
canvas.drawBitmap(image, 0f, 0f, null); // draw old image on the background
image.recycle(); 

Ответ 2

У меня была аналогичная проблема. Следующий код демонстрирует эту проблему.

final DisplayMetrics metrics = new DisplayMetrics();
getWindowManager().getDefaultDisplay().getMetrics(metrics);

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

mImageReader = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, MAX_IMAGES);

mVirtualDisplay = mMediaProjection.createVirtualDisplay("ScreenCaptureTest",
        width, height, densityDpi,
        DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
        mImageReader.getSurface(), null, null);

Замените это:

getWindowManager().getDefaultDisplay().getMetrics(metrics);

При этом:

getWindowManager().getDefaultDisplay().getRealMetrics(metrics);

Исправлено. Проблема в том, что декорации вокруг изображения искажают фактическое разрешение экрана. getMetrics() возвращает высоту (или ширину в ландшафте), которая не является точным, и имеет выходы дома, назад и т.д. Фактическая область отображения, доступная для разработчиков, - это (1440 x 2326... или что-то в этом роде). Но, конечно, захваченное изображение будет полным разрешением экрана 1440 X 2560.

Ответ 3

Основываясь на ваших комментариях, я думаю, что это то, что вы ищете

    Bitmap bitmap; //field
    Bitmap  croppedBitmap; // field
    Image image;// field
    Handler mHandler; //field


    new Thread() {
        @Override
        public void run() {
            Looper.prepare();
            mHandler = new Handler();
            Looper.loop();
        }
    }.start();

    imageAvailableListener = new ImageReader.OnImageAvailableListener {
    @Override
    public void onImageAvailable(ImageReader reader) {

        try {
            image = reader.acquireLatestImage();
            bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
            Rect rect = image.getCropRect();
            croppedBitmap =  Bitmap.createBitmap(bitmap,rect.left,rect.top,rect.width(),rect.height());

            \\Do whatever here...


            image.close();
            } catch (Exception e) {
                e.printStackTrace();
            } finally {

               if (bitmap!=null) {
                   bitmap.recycle();
               }

              if (croppedBitmap!=null) {
                   bitmap.recycle();
               }

              if (image!=null) {
                   image.close();
               }
           }
        }
    }
    imageReader.setOnImageAvailableListener(imageAvailableListener, mHandler);