I managed to get screenshots but the result is like this:
Original:
This is my code which i took from a few sources:
final ImageReader ir = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2);
VirtualDisplay vd= mediaProjection.createVirtualDisplay("screen", width, height, dpi,
DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC, ir.getSurface(), null, null);
final String path=getActivity().getFilesDir().getAbsolutePath()+"/myscreen.jpg";
ir.setOnImageAvailableListener(new OnImageAvailableListener() {
// @Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
FileOutputStream fos = null;
Bitmap bitmap = null;
try {
image = ir.acquireLatestImage();
fos = new FileOutputStream( path);
final Image.Plane[] planes = image.getPlanes();
final Buffer buffer = planes[0].getBuffer().rewind();
bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
bitmap.compress(CompressFormat.JPEG, 85, fos);
image.close();
} catch (Exception e) {
e.printStackTrace();
........
........
It's the width and height of your bitmap that's off--atleast your distorted image looks just like what I was seeing. Here's how I got it working.
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * imageReader.getWidth();
bitmap = Bitmap.createBitmap(imageReader.getWidth() + rowPadding / pixelStride,
imageReader.getHeight(), Bitmap.Config.ARGB_8888);
And it's important to use the imageReaders width/height (not the images).
When creating the imageReader/virtualDisplay objects I use the following method to get the display metrics.
public static DisplayMetrics getScreenMetrics(Context context) {
WindowManager wm = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = wm.getDefaultDisplay();
DisplayMetrics dm = new DisplayMetrics();
display.getMetrics(dm);
return dm;
}
...
ImageReader imageReader = ImageReader.newInstance(displayMetrics.widthPixels, displayMetrics.heightPixels, PixelFormat.RGBA_8888, 2);
I've learned this from trial and error, so I apologize for not being able to give an explanation why.
I am using Xamarin(.NET) and was able to FINALLY get this working, except for one problem (java code):
final ImageReader ir = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2);
PixelFormat.RGBA_8888 is not a valid parameter as the ImageReader requires an ImageFormatType. The following .NET code solves this:
_mImageReader = ImageReader.NewInstance(_mWidth, _mHeight, (ImageFormatType)Format.Rgba8888, 2);
Notice the casting of the follwing, with Format being of the Android.Graphics.Format enum:
(ImageFormatType)Format.Rgba8888
I hope this helps someone out there using Xamarin as this caused a ton of frustration over the last day!
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With