gpt4 book ai didi

java - 将 MediaProjection 虚拟显示器的输出捕获到 ImageReader 的系统错误

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:54:07 26 4
gpt4 key购买 nike

我正在开发一个需要将屏幕捕获到位图以进行传输的应用程序。我正在尝试使用新的 Android 5.0 android.media.projection APIs进行屏幕捕获。

此 API 的工作流以调用

告终
mediaProjection.createVirtualDisplay("Test Screen", WIDTH, HEIGHT, DPI,
DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, surface, null, null);

在我最初尝试进行此捕获时,我从 SurfaceView 获取表面对象。这工作正常;最终结果是在屏幕上绘制的显示的微小副本(导致 Droste Effect )

我认为该功能已接近完成,但是 I then discovered SurfaceViews(从代码的角度来看)不可读;你不能从他们那里得到位图。

在寻找其他解决方案时,我遇到了 this question这与我的目标非常相似,在该线程中它是 suggested使用 ImageReader 而不是 SurfaceView 获取传递给 createVirtualDisplay API 调用的 Surface。

但是,当我更改我的代码以使用 ImageReader 代替 SurfaceView 时,我会遇到运行时 logcat 错误(没有异常(exception)),并且永远不会调用 ImageReader 的回调函数。 createVirtualDisplay 调用还返回一个看似有效的 VirtualDisplay 对象。

这是日志:

9230-9270/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: createGraphicBuffer failed
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count
9230-9246/com.android.techrocket9.nanoid E/BufferQueueProducer﹕ [unnamed-9230-0] dequeueBuffer: can't dequeue multiple buffers without setting the buffer count

第二行在停止出现之前重复了约 100 次。

通过调试器,我看到第一个错误发生在 createVirtualDisplay 调用期间,所有其他错误发生在执行返回系统代码后的某个时间点。

only meaningful result因为此错误与 Kitkat 中的一个问题有关,我尝试使用的 API 不存在。尽管如此,我还是尝试了 fix suggested here (将 android:hardwareAccelerated="false" 放在 list 中)。这并没有改变应用程序的行为。

如何“设置缓冲区计数”或以其他方式解决此错误并将屏幕作为位图获取?

附言我的开发平台是 Nexus 6。

完整的代码块,根据要求:

MediaProjection mediaProjection = mgr.getMediaProjection(resultCode, data);
ImageReader ir = ImageReader.newInstance(WIDTH, HEIGHT, ImageFormat.JPEG, 5);
VirtualDisplay v = mediaProjection.createVirtualDisplay("Test Screen", WIDTH, HEIGHT, getApplicationContext().getResources().getDisplayMetrics().densityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR, ir.getSurface(), null, null);

编辑:关于伪影问题,这是我用来从图像中获取位图并显示它的代码:

 public void onImageAvailable(ImageReader reader) {
Image image = null;
ByteArrayOutputStream bos = null;

try {
image = reader.acquireLatestImage();
if (null == image){
return;
}
bos = new ByteArrayOutputStream();
final Image.Plane[] planes = image.getPlanes();
final ByteBuffer buffer = (ByteBuffer) planes[0].getBuffer().rewind();
final Bitmap bitmap = Bitmap.createBitmap(image.getWidth(), image.getHeight(), Bitmap.Config.ARGB_8888);
bitmap.copyPixelsFromBuffer(buffer);
//bitmap.compress(Bitmap.CompressFormat.WEBP, 50, bos);

runOnUiThread(new Runnable() {
public void run() {
iv.setImageBitmap(bitmap);
}
});

最佳答案

我想我现在可以回答这个问题了,我遇到了同样的问题,在我将 ImageFormat.JPEG 更改为 PixelFormat.RGBA_8888 之后一切正常。似乎不支持 ImageFormat.JPEG。

您需要使用以下代码来获取正确的位图:

                    int width = img.getWidth();
int height = img.getHeight();
int pixelStride = planes[0].getPixelStride();
int rowStride = planes[0].getRowStride();
int rowPadding = rowStride - pixelStride * width;
byte[] newData = new byte[width * height * 4];

int offset = 0;
bitmap = Bitmap.createBitmap(metrics,width, height, Bitmap.Config.ARGB_8888);
ByteBuffer buffer = planes[0].getBuffer();
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
int pixel = 0;
pixel |= (buffer.get(offset) & 0xff) << 16; // R
pixel |= (buffer.get(offset + 1) & 0xff) << 8; // G
pixel |= (buffer.get(offset + 2) & 0xff); // B
pixel |= (buffer.get(offset + 3) & 0xff) << 24; // A
bitmap.setPixel(j, i, pixel);
offset += pixelStride;
}
offset += rowPadding;
}

这样一来,位图的内容就是你想要的。

PS:我真的很想说,android的文档很烂。我们需要调查太多细节才能正确使用 sdk api。

关于java - 将 MediaProjection 虚拟显示器的输出捕获到 ImageReader 的系统错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27219799/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com