Android Take Screenshot of Surface View Shows Black Screen

前端 未结 4 1721
花落未央
花落未央 2020-11-22 04:58

I am attempting to Take a Screenshot of my Game through code and Share it through an Intent. I able to do of those things, however the screenshot always appears black. Here

4条回答
  •  北荒
    北荒 (楼主)
    2020-11-22 05:37

    Update 2020 view.setDrawingCacheEnabled(true) is deprecated in API 28

    If you are using normal View then you can create a canvas with the specified bitmap to draw into. Then ask the view to draw over that canvas and return bitmap filled by Canvas

     /**
         * Copy View to Canvas and return bitMap
         */
        fun getBitmapFromView(view: View): Bitmap? {
            var bitmap =
                Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
            val canvas = Canvas(bitmap)
            view.draw(canvas)
            return bitmap
        }
    

    Or you can fill the canvas with a default color before drawing it with the view:

        /**
         * Copy View to Canvas and return bitMap and fill it with default color
         */
        fun getBitmapFromView(view: View, defaultColor: Int): Bitmap? {
            var bitmap =
                Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
            var canvas = Canvas(bitmap)
            canvas.drawColor(defaultColor)
            view.draw(canvas)
            return bitmap
        }
    

    The above approach will not work for the surface view they will drawn as a hole in the screenshot.

    For surface view since Android 24, you need to use Pixel Copy.

        /**
         * Pixel copy to copy SurfaceView/VideoView into BitMap
         */
         fun usePixelCopy(videoView: SurfaceView,  callback: (Bitmap?) -> Unit) {
            val bitmap: Bitmap = Bitmap.createBitmap(
                videoView.width,
                videoView.height,
                Bitmap.Config.ARGB_8888
            );
            try {
            // Create a handler thread to offload the processing of the image.
            val handlerThread = HandlerThread("PixelCopier");
            handlerThread.start();
            PixelCopy.request(
                videoView, bitmap,
                PixelCopy.OnPixelCopyFinishedListener { copyResult ->
                    if (copyResult == PixelCopy.SUCCESS) {
                        callback(bitmap)
                    }
                    handlerThread.quitSafely();
                },
                Handler(handlerThread.looper)
            )
            } catch (e: IllegalArgumentException) {
                callback(null)
                // PixelCopy may throw IllegalArgumentException, make sure to handle it
                e.printStackTrace()
            }
        }
    

    This approach can take a screenshot of any subclass of Surface Vie eg VideoView

    Screenshot.usePixelCopy(videoView) { bitmap: Bitmap? ->
                    processBitMap(bitmap)
                }
    

提交回复
热议问题