2015-12-09 7 views
10

я работаю над записью мой экран с MediaProjection следующимскриншот Android 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); 

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

enter image description here

РЕДАКТИРОВАТЬ

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

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

+0

Сфотографируйте экран (со вторым устройством) и сравните два. Вы теряете пиксели от края экрана? Представлен ли весь дисплей? Является ли приложение полноэкранным - у оригинала есть видимая панель навигации/панель уведомлений? – fadden

+0

@ fadden picture содержит полноэкранный просмотр, включая навигационную панель, notif-бар и представляет весь дисплей, включая черную рамку за пределами изображения – AMD

+0

@AMD вы дали мой код попробовать? –

ответ

1

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

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); 
+0

спасибо, что я пробовал ваш код, он удаляет верхнюю и нижнюю прописку, но влево-вправо заполняется так, как есть, а также показывает белую рамку вне изображения – AMD

+0

См. Обновленный код –

+0

для записи mediarecorder.getSurface используется вместо imageReader.getSurface – AMD

5

Если вы не имеете контроля над изображением самостоятельно, вы можете изменить его, сделать что-то подобное, предполагая, что ваш 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(); 
+0

i абрикация вашего ответа, но мне это нужно во время медиапроекции, как функция захвата сурфактов, см. Обновленный вопрос – AMD

3

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

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.