如何用java在android中捕捉4k屏幕?

zsohkypk  于 2021-06-30  发布在  Java
关注(0)|答案(0)|浏览(339)

你好,在发布这个问题之前,我仔细检查了大多数堆栈溢出的问题都没有帮助解决我的问题,我也读了这篇文章说,安卓马什梅洛和以上确实支持4k,但我只是找不到一个方法来实现下面是我的问题场景
我需要捕获4k的显示,然后将其显示到连接到android端口的外部显示器上,这与手机镜像有些相似,但我正在从头开始实现它我需要在渲染之前处理位图,这就是为什么我不能仅仅依赖本机镜像的原因。
到目前为止,我所做的是,我成功地在带有全屏标志的辅助显示器中启动了viewer活动,它只包含一个imageview,显示通过广播接收器接收的位图。用虚拟显示启动媒体投影的后台服务,其度量与默认显示相同。这个场景运行良好,但4k支持还没有发挥作用,这方面的android文档还不太清楚。
下面的代码是捕获函数,它是我的捕获服务的成员。由于其他功能与屏幕捕获无关,所以我没有发布其他功能,它们与服务处理相关。

private void ProjectionRelatedStuff()
    {
        mProjectionManager = (MediaProjectionManager) getSystemService(MEDIA_PROJECTION_SERVICE);
        new Thread()
        {
            @Override
            public void run() {
                Looper.prepare();
                mHandler = new Handler();
                Looper.loop();
            }
        }.start();

        mProjection = mProjectionManager.getMediaProjection(Utility.CODE, Utility.DATA);
        if (mProjection != null)
        {
            int flags = DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR | DisplayManager.VIRTUAL_DISPLAY_FLAG_PUBLIC;
            final DisplayMetrics _metrics = new DisplayMetrics();
            Utility.Def_Display.getMetrics(_metrics);

            final ImageReader _reader = ImageReader.newInstance(_metrics.widthPixels, _metrics.heightPixels, PixelFormat.RGBA_8888, 2);
            _reader.setOnImageAvailableListener(new ImageReader.OnImageAvailableListener() {
                @Override
                public void onImageAvailable(ImageReader reader)
                {
                    Bitmap bitmap = null;
                    Image img = null;
                    try
                    {
                        img = reader.acquireLatestImage();
                        if (img != null) {
                            Image.Plane[] planes = img.getPlanes();
                            if (planes[0].getBuffer() == null) {
                                return;
                            }
                            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, _metrics.widthPixels, _metrics.heightPixels, 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;
                            }

                            Intent intent = new Intent(Utility.BROADCAST);
                            intent.putExtra("bitmap", Bitmap.createScaledBitmap(bitmap, 3840, 2160, false));
                            LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(intent);

                            img.close();
                        }

                    } catch (Exception e) {
                        e.printStackTrace();
                    } finally {
                        if (null != bitmap) {
                            bitmap.recycle();
                        }
                        if (null != img) {
                            img.close();
                        }
                    }
                }
            }, mHandler);

            mProjection.createVirtualDisplay("screencap", _metrics.widthPixels, _metrics.heightPixels, _metrics.densityDpi, flags, _reader.getSurface(), null, mHandler);
        }
    }

目前我面临以下两个问题
如果我硬编码4k结果,我无法捕获4k中的显示,因为它会引发异常
获得的位图从广播发送到查看器活动,渲染在不平滑的imageview中完成(我需要使用canvas吗?)

暂无答案!

目前还没有任何答案,快来回答吧!

相关问题