Black edges around the taken screenshot

匿名 (未验证) 提交于 2019-12-03 01:25:01

问题:

I'm following this example :

package com.mtsahakis.mediaprojectiondemo;  import android.app.Activity; import android.content.Context; import android.content.Intent; import android.graphics.Bitmap; import android.graphics.Bitmap.CompressFormat; import android.graphics.PixelFormat; import android.graphics.Point; import android.hardware.display.DisplayManager; import android.hardware.display.VirtualDisplay; import android.media.Image; import android.media.ImageReader; import android.media.projection.MediaProjection; import android.media.projection.MediaProjectionManager; import android.os.Bundle; import android.os.Handler; import android.os.Looper; import android.util.DisplayMetrics; import android.util.Log; import android.view.Display; import android.view.OrientationEventListener; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button;  import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.nio.ByteBuffer;   public class ScreenCaptureImageActivity extends Activity {      private static final String TAG = ScreenCaptureImageActivity.class.getName();     private static final int REQUEST_CODE = 100;     private static String STORE_DIRECTORY;     private static int IMAGES_PRODUCED;     private static final String SCREENCAP_NAME = "screencap";     private static final int VIRTUAL_DISPLAY_FLAGS = DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;     private static MediaProjection sMediaProjection;      private MediaProjectionManager mProjectionManager;     private ImageReader mImageReader;     private Handler mHandler;     private Display mDisplay;     private VirtualDisplay mVirtualDisplay;     private int mDensity;     private int mWidth;     private int mHeight;     private int mRotation;     private OrientationChangeCallback mOrientationChangeCallback;      private class ImageAvailableListener implements ImageReader.OnImageAvailableListener {         @Override         public void onImageAvailable(ImageReader reader) {             Image image = null;             FileOutputStream fos = null;             Bitmap bitmap = null;              try {                 image = mImageReader.acquireLatestImage();                 if (image != null) {                     Image.Plane[] planes = image.getPlanes();                     ByteBuffer buffer = planes[0].getBuffer();                     int pixelStride = planes[0].getPixelStride();                     int rowStride = planes[0].getRowStride();                     int rowPadding = rowStride - pixelStride * mWidth;                      // create bitmap                     bitmap = Bitmap.createBitmap(mWidth + rowPadding / pixelStride, mHeight, Bitmap.Config.ARGB_8888);                     bitmap.copyPixelsFromBuffer(buffer);                      // write bitmap to a file                     fos = new FileOutputStream(STORE_DIRECTORY + "/myscreen_" + IMAGES_PRODUCED + ".png");                     bitmap.compress(CompressFormat.JPEG, 100, fos);                      IMAGES_PRODUCED++;                     Log.e(TAG, "captured image: " + IMAGES_PRODUCED);                 }              } catch (Exception e) {                 e.printStackTrace();             } finally {                 if (fos!=null) {                     try {                         fos.close();                     } catch (IOException ioe) {                         ioe.printStackTrace();                     }                 }                  if (bitmap!=null) {                     bitmap.recycle();                 }                  if (image!=null) {                     image.close();                 }             }         }     }      private class OrientationChangeCallback extends OrientationEventListener {         public OrientationChangeCallback(Context context) {             super(context);         }          @Override         public void onOrientationChanged(int orientation) {             synchronized (this) {                 final int rotation = mDisplay.getRotation();                 if (rotation != mRotation) {                     mRotation = rotation;                     try {                         // clean up                         if(mVirtualDisplay != null) mVirtualDisplay.release();                         if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);                          // re-create virtual display depending on device width / height                         createVirtualDisplay();                     } catch (Exception e) {                         e.printStackTrace();                     }                 }             }         }     }      private class MediaProjectionStopCallback extends MediaProjection.Callback {         @Override         public void onStop() {             Log.e("ScreenCapture", "stopping projection.");             mHandler.post(new Runnable() {                 @Override                 public void run() {                     if(mVirtualDisplay != null) mVirtualDisplay.release();                     if(mImageReader != null) mImageReader.setOnImageAvailableListener(null, null);                     if(mOrientationChangeCallback != null) mOrientationChangeCallback.disable();                     sMediaProjection.unregisterCallback(MediaProjectionStopCallback.this);                 }             });         }     }      /****************************************** Activity Lifecycle methods ************************/     @Override     protected void onCreate(Bundle savedInstanceState) {         super.onCreate(savedInstanceState);         setContentView(R.layout.activity_main);          // call for the projection manager         mProjectionManager = (MediaProjectionManager) getSystemService(Context.MEDIA_PROJECTION_SERVICE);          // start projection         Button startButton = (Button)findViewById(R.id.startButton);         startButton.setOnClickListener(new OnClickListener() {              @Override             public void onClick(View v) {                 startProjection();             }         });          // stop projection         Button stopButton = (Button)findViewById(R.id.stopButton);         stopButton.setOnClickListener(new OnClickListener() {              @Override             public void onClick(View v) {                 stopProjection();             }         });          // start capture handling thread         new Thread() {             @Override             public void run() {                 Looper.prepare();                 mHandler = new Handler();                 Looper.loop();             }         }.start();     }      @Override     protected void onActivityResult(int requestCode, int resultCode, Intent data) {         if (requestCode == REQUEST_CODE) {             sMediaProjection = mProjectionManager.getMediaProjection(resultCode, data);              if (sMediaProjection != null) {                 File externalFilesDir = getExternalFilesDir(null);                 if (externalFilesDir != null) {                     STORE_DIRECTORY = externalFilesDir.getAbsolutePath() + "/screenshots/";                     File storeDirectory = new File(STORE_DIRECTORY);                     if (!storeDirectory.exists()) {                         boolean success = storeDirectory.mkdirs();                         if (!success) {                             Log.e(TAG, "failed to create file storage directory.");                             return;                         }                     }                 } else {                     Log.e(TAG, "failed to create file storage directory, getExternalFilesDir is null.");                     return;                 }                  // display metrics                 DisplayMetrics metrics = getResources().getDisplayMetrics();                 mDensity = metrics.densityDpi;                 mDisplay = getWindowManager().getDefaultDisplay();                  // create virtual display depending on device width / height                 createVirtualDisplay();                  // register orientation change callback                 mOrientationChangeCallback = new OrientationChangeCallback(this);                 if (mOrientationChangeCallback.canDetectOrientation()) {                     mOrientationChangeCallback.enable();                 }                  // register media projection stop callback                 sMediaProjection.registerCallback(new MediaProjectionStopCallback(), mHandler);             }         }     }      /****************************************** UI Widget Callbacks *******************************/     private void startProjection() {         startActivityForResult(mProjectionManager.createScreenCaptureIntent(), REQUEST_CODE);     }      private void stopProjection() {         mHandler.post(new Runnable() {             @Override             public void run() {                 if (sMediaProjection != null) {                     sMediaProjection.stop();                 }             }         });     }      /****************************************** Factoring Virtual Display creation ****************/     private void createVirtualDisplay() {         // get width and height         Point size = new Point();         mDisplay.getSize(size);         mWidth = size.x;         mHeight = size.y;          // start capture reader         mImageReader = ImageReader.newInstance(mWidth, mHeight, PixelFormat.RGBA_8888, 2);         mVirtualDisplay = sMediaProjection.createVirtualDisplay(SCREENCAP_NAME, mWidth, mHeight, mDensity, VIRTUAL_DISPLAY_FLAGS, mImageReader.getSurface(), null, mHandler);         mImageReader.setOnImageAvailableListener(new ImageAvailableListener(), mHandler);     } } 

to take a screenshot on Android ver >=21.

The problem with that example is that once I take the screenshot , there are black edges on the top , right & bottom of the Image.

I can't see where is the problem since the given Width and Height to both the VirtualDisplay and the Bitmap are correct, what I'm missing here?

回答1:

Problem is probably the size of the virtual display.

mDisplay.getSize(size); 

may return something different than the real size of the device if your device have a virtual navigation bar (usually swipe from bottom of the screen to display it).

mDisplay.getRealSize(size); 

will probably fix your problem with black edges.



回答2:

Rect rect = image.getCropRect(); bitmap = Bitmap.createBitmap(bitmap, rect.left, rect.top, rect.width(), rect.height()); 


易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!