我编写了使用MediaProjection类捕获图像的测试应用程序。
imageReader = ImageReader.newInstance(currentWidth, currentHeight, PixelFormat.RGBA_8888, 2);
imageReader.setOnImageAvailableListener(this, null);
virtualDisplay = mediaProjection.createVirtualDisplay("captureDisplay",
currentWidth, currentHeight, DisplayManager.VIRTUAL_DISPLAY_FLAG_OWN_CONTENT_ONLY |
DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC|
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR |
DisplayManager.VIRTUAL_DISPLAY_FLAG_SECURE |
DisplayManager.VIRTUAL_DISPLAY_FLAG_PRESENTATION, Screen.getDensity(mContext), imageReader.getSurface(), null, null);
// DisplayManager标志只是路径
和onImageAvailable(ImageReader reader)
方法
我试图获得如下图像:
Bitmap bitmap;
Image mImage = null;
try {
mImage = mImageReader .acquireLatestImage();
if (img != null) {
final Image.Plane[] planes = mImage.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * mImage.getWidth();
bitmap = Bitmap.createBitmap(mImage.getWidth() + rowPadding/pixelStride, mImage.getHeight(), Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
ByteArrayOutputStream stream = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, stream);
byte[] rawData = lastImageAcquiredRaw = stream.toByteArray();
if (rawData != null) {
Bitmap fullScreen = BitmapFactory.decodeByteArray(rawData, 0, rawData.length);
savebitmap(fullScreen,"image",i); //Saving bitmap in storage
}
}
直到现在我没事,当我的应用程序处于横向时,我正在获得正确的图像。面临的问题是方向改变,我没有得到正确的图像。有时再次回到景观也没有正确捕捉。
我经历了ImageReader.java类。没有提到需要处理方向变化。
尝试使用acquireNextImageNoThrowISE(),acquireNextImage()但没有用。
是否有人尝试或有可能在方向上获得正确的图像?
请帮助我获得正确的图像。
答案 0 :(得分:1)
我知道这篇文章有点陈旧,但最近几天我正在扼杀同样的事情。我也在使用MediaProjection API,VirtualDisplay和ImageReader的表面。我要展示的解决方案不是100%全面证明,所以如果有人有任何有用的建议是非常受欢迎的。
第一步:创建虚拟展示后添加OrientationChangeCallback
OrientationChangeCallback orientationChangeCallback = new OrientationChangeCallback(context);
if (orientationChangeCallback.canDetectOrientation()) {
orientationChangeCallback.enable();
}
第二步:定义方向回调,实质上重启捕获
private class OrientationChangeCallback extends OrientationEventListener {
OrientationChangeCallback(Context context) {
super(context);
}
@Override
public void onOrientationChanged(int orientation) {
final int rotation = mDisplay.getRotation();
if(rotation != mRotation) {
mRotation = rotation;
if (mVirtualDisplay != null) {
mVirtualDisplay.release();
}
if (mImageReader != null) {
mImageReader.setOnImageAvailableListener(null, null);
}
if (!mProjectionStopped) {
createVirtualDisplay();
}
}
}
}
请注意,我持有对ImageReader和VirtualDisplay的引用,并且还有volatile boolean mRotation
来检查屏幕是否实际旋转。
我遇到的问题是,在某些设备(包括Nexus 5X)上,图像在X编号或旋转(通常为10-20)后可能会损坏。如果我再次旋转设备,则可以正确捕获图像。在快速设备(Google Pixel)上,我无法复制损坏的图像问题,所以我猜它可能是同步问题。