【问题标题】:MediaProjection producing distorted screenshotMediaProjection 产生扭曲的屏幕截图
【发布时间】:2016-01-29 19:00:22
【问题描述】:

我设法得到了截图,但结果是这样的:

原文:

这是我从几个来源获取的代码:

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();
             ........
             ........

【问题讨论】:

  • 即兴发挥,您的width 计算可能已关闭,因为它似乎没有考虑像素步长和行步长。请参阅this chunk of code 了解我是如何做到的。
  • 为什么是width>>1?顺便说一句,把bitmapWidth=width + rowPadding / pixelStride 工作,但现在我在右边有一个 300 像素宽的黑条,
  • "为什么是宽度>>1?" ——我没看到,抱歉。 “现在我在右侧有一个 300 像素宽的黑条”——这是因为您要求的尺寸与实际图像的尺寸之间存在差异。如果您继续查看我的代码清单,越过突出显示的部分,您将看到我在哪里将原始位图裁剪为所需的大小,然后使用裁剪的部分。

标签: android android-screen android-mediaprojection


【解决方案1】:

这是您的位图的宽度和高度不正确——至少您扭曲的图像看起来就像我看到的一样。以下是我的工作方式。

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);

使用 imageReaders 的宽度/高度(不是图像)很重要。

在创建 imageReader/virtualDisplay 对象时,我使用以下方法来获取显示指标。

   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);

我从反复试验中了解到这一点,因此对于无法解释原因,我深表歉意。

【讨论】:

    【解决方案2】:

    我正在使用 Xamarin(.NET) 并且能够最终得到这个工作,除了一个问题(java 代码):

    final ImageReader ir = ImageReader.newInstance(width, height, PixelFormat.RGBA_8888, 2);
    

    PixelFormat.RGBA_8888 不是有效参数,因为 ImageReader 需要 ImageFormatType。下面的 .NET 代码解决了这个问题:

    _mImageReader = ImageReader.NewInstance(_mWidth, _mHeight, (ImageFormatType)Format.Rgba8888, 2);
    

    注意下面的转换,Format 是 Android.Graphics.Format 枚举:

    (ImageFormatType)Format.Rgba8888

    我希望这对使用 Xamarin 的人有所帮助,因为这在最后一天造成了很多挫败感!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-06
      • 1970-01-01
      • 1970-01-01
      • 2018-03-03
      • 1970-01-01
      相关资源
      最近更新 更多