2015-12-09 18 views
10

Sto lavorando a registrare il mio schermo con MediaProjection come segueAndroid mediaprojection screenshot contiene cornice nera

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

Il problema è che le immagini acquisite contiene cornice nera come immagine qui sotto.

enter image description here

EDIT

Il problema di cui sopra possono essere risolti con operazioni bitmap.

Tuttavia, ora sto cercando una soluzione che può essere applicata a MediaProjection o a SurfaceView di ImageReader per implementare la registrazione del dispositivo.

+0

Scatta una foto dello schermo (con un secondo dispositivo) e confronta i due. Stai perdendo pixel dal bordo dello schermo? L'intero display è rappresentato? L'app è a schermo intero - l'originale ha una barra di navigazione/barra di notifica visibile? – fadden

+0

L'immagine di fadden contiene la visualizzazione a schermo intero inclusa la barra di navigazione, la barra di notifica e rappresenta l'intero display inclusa la cornice nera all'esterno dell'immagine – AMD

+0

@AMD hai provato a provare il mio codice? –

risposta

1

sulla base di osservazioni Penso che questo è quello che stai cercando

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

grazie ho provato il codice rimuove il rivestimento superiore e inferiore ma il pad sinistro-destro è rubato com'è e mostra anche il bordo bianco all'esterno dell'immagine – AMD

+0

Vedere il codice aggiornato –

+0

per la registrazione mediarecorder.getSurface viene utilizzato invece imageReader.getSurface – AMD

5

Se non si ha il controllo sull'immagine da soli, è possibile modificarlo facendo qualcosa di simile, supponendo che il bitmap si chiama immagine .

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

io apriciare la tua risposta ma ne ho bisogno durante la proiezione multimediale come la funzione Perfact Capture, vedi domanda aggiornata – AMD

3

Ho avuto un problema simile. Il seguente codice presenta questo problema.

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

Sostituzione questo:

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

Con questo:

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

lo ripara. Il problema è che le decorazioni intorno all'immagine corrompono la reale risoluzione dello schermo. getMetrics() restituisce un'altezza (o larghezza in orizzontale) che non è accurata e ha i tasti home, back, etc, sottratti. L'area di visualizzazione effettiva disponibile per gli sviluppatori è (1440 x 2326 ... o qualcosa del genere). Ma naturalmente, l'immagine catturata sarà la piena risoluzione dello schermo 1440 X 2560.

Problemi correlati