- iOS/Objective-C 元类和类别
- objective-c - -1001 错误,当 NSURLSession 通过 httpproxy 和/etc/hosts
- java - 使用网络类获取 url 地址
- ios - 推送通知中不播放声音
我正在使用 Android ImageReader 类从 MediaProjection.createVirtualDisplay 方法接收位图。
到目前为止,我的代码如下所示:
mProjection.createVirtualDisplay("test", width, height, density, flags, mImageReader.getSurface(), new VirtualDisplayCallback(), mHandler);
mImageReader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
@Override
public void onImageAvailable(ImageReader reader) {
Image image = null;
try {
image = mImageReader.acquireLatestImage();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
final byte[] data = new byte[buffer.capacity()];
buffer.get(data);
final Bitmap bitmap = BitmapFactory.decodeByteArray(data, 0, data.length);
if (bitmap==null)
Log.e(TAG, "bitmap is null");
} catch (Exception e) {
if (image!=null)
image.close();
}
}
}, mHandler);
问题是 BitmapFactory 无法将 data[] 解码回 Bitmap,即 BitmapFactory 总是返回 null。我从 logcat 看到的唯一消息来自 android_media_ImageReader.cpp 并且像这样:
D/ImageReader_JNI(1432): ImageReader_imageSetup: Receiving JPEG in HAL_PIXEL_FORMAT_RGBA_8888 buffer.
W/ImageReader_JNI(1432): Image_getJpegSize: No JPEG header detected, defaulting to size=width=3891200
acquireLatestImage 返回的图像对象不为空但也不是有效的 JPEG,我尝试检查以下测试但失败了:
if((buf [0] & 0xFF) == 0xFF && (buf[1] & 0xFF) == 0xD8 && (buf[2] & 0xFF) == 0xFF && (buf[3] & 0xFF) == 0xE0)
Log.e(TAG, "is JPG");
else
Log.e(TAG, "not a valid JPG");
目前我唯一怀疑的是我正在测试的 Android 5.0 模拟器无法处理 API 调用。
有什么想法吗?
最佳答案
@charlesjean 回答的代码有效,但我不想自己生成每个像素。从 ImageReader 获取图像的更好方法是创建大小合适的位图并使用方法 copyPixelsFromBuffer()。按如下方式创建 ImageReader:
mImageReader = ImageReader.newInstance(mWidth, mHeight, ImageFormat.RGB_565, 2);
然后您可以使用下面的代码从 mImageReader 获取图像。
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = planes[0].getBuffer();
int offset = 0;
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.RGB_565);
bitmap.copyPixelsFromBuffer(buffer);
image.close();
我在 blog post 中描述了使用 MediaProjection API 捕获屏幕的过程以及大多数人在从 ImageReader 获取图像时所犯的错误。如果有兴趣,您可以阅读。
关于Android ImageReader.acquireLatestImage 返回无效的 JPG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26673127/
我正在研究 Camera2 API 以连续拍照并且工作正常,在这里,我可以使用以下代码保存捕获的图像: ImageReader.OnImageAvailableListener readerListe
我正在使用 Android ImageReader 类从 MediaProjection.createVirtualDisplay 方法接收位图。 到目前为止,我的代码如下所示: mProjectio
我目前正在使用 Camera2 API,并创建了一个新的 ImageReader.OnImageAvailableListener 对象。当然,它必须实现 onImageAvailable(Image
我是一名优秀的程序员,十分优秀!