简体   繁体   English

使用 PixelCopy.request() 保存 SurfaceView 的屏幕截图返回黑色 bitmap

[英]Using PixelCopy.request() to save a screenshot of a SurfaceView returns a black bitmap

I'm developing an app where I need to save the content drawn on a SurfaceView canvas to an image file.我正在开发一个应用程序,我需要将在 SurfaceView canvas 上绘制的内容保存到图像文件中。 I read that the PixelCopy API can be used to do this after API level 24, but so far my code only returns an empty, black bitmap.我读到 PixelCopy API 可用于在 API 级别 24 之后执行此操作,但到目前为止我的代码仅返回一个空的黑色 bitmap。

Here's what I tried:这是我尝试过的:

private CustomView my_view; //CustomView extends SurfaceView implements SurfaceHolder.Callback

private void captureImage()
{
  Bitmap bitmap = Bitmap.createBitmap(my_view.getWidth(), my_view.getHeight(), Bitmap.Config.ARGB_8888);

  PixelCopy.request(my_view, bitmap, new PixelCopy.OnPixelCopyFinishedListener() {
      @Override
      public void onPixelCopyFinished(int copyResult) 
      {
        try {
           saveImageToFile(bitmap, "myfilename"); //This saved image is empty and black
        } 
        catch (IOException ignored) {
        }
      }
    }, new Handler(Looper.getMainLooper()));
}

If I try the old approach of using getDrawingCache() as shown below, then everything works as expected and I get an image with all the content rendered on the SurfaceView.如果我尝试使用getDrawingCache()的旧方法,如下所示,那么一切都会按预期工作,并且我会得到一张图像,其中包含在 SurfaceView 上呈现的所有内容。

my_view.setDrawingCacheEnabled(true);
Bitmap bitmap = my_view.getDrawingCache(); //This works
try {
  saveImageToFile(bitmap, "myfilename");
} 
catch (IOException ignored) {
}
my_view.destroyDrawingCache();
my_view.setDrawingCacheEnabled(false);

However, I would like to use the PixelCopy API since the getDrawingCache() function has been deprecated.但是,我想使用PixelCopy API,因为getDrawingCache() function 已被弃用。 Does anyone know what the issue might be with my PixelCopy approach above?有谁知道我上面的 PixelCopy 方法可能有什么问题?

Have you checked the copyResult if it is success?如果成功,你检查过copyResult了吗? I recently used PixelCopy , and it worked very well.我最近使用了 PixelCopy ,效果很好。 I will provide the code.我会提供代码。

First we get the view coordinates on the window as a Rect :首先,我们将 window 上的视图坐标作为Rect

fun getViewRect(screenshotView: View): Rect {
    val viewPadding = 8.toIntPixel(this)

    val viewLocation = IntArray(2)
    screenshotView.getLocationInWindow(viewLocation)

    return Rect(
        viewLocation[0] - viewPadding,
        viewLocation[1] - viewPadding,
        viewLocation[0] + screenshotView.width + viewPadding,
        viewLocation[1] + screenshotView.height + viewPadding
    )
}

then we write a function to take a screenshot:然后我们写一个function来截图:

fun takeScreenshot(
    activity: Activity,
    viewRect: Rect,
    onSuccess: (Bitmap) -> Unit
) {
    val bitmap = Bitmap.createBitmap(viewRect.width(), viewRect.height(), Bitmap.Config.ARGB_8888)
    PixelCopy.request(activity.window, viewRect, bitmap, 
        { copyResult ->
            if (copyResult == PixelCopy.SUCCESS) {
                onSuccess(bitmap)
            } else {
                error("problem with taking a screenshot")
            }
            bitmap.recycle()
        },
        Handler(Looper.getMainLooper())
    )
}

then you can call the function:然后你可以拨打function:

takeScreenshot(activity, activity.getViewRect()) { bitmap ->
    saveImageToFile(bitmap, "myfilename.png")
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM