android保存surface到bitmap

最近做一个项目,项目中用到显示屏比较大,3840*1080,为了充分发挥大屏的显示区域,有一个分屏的功能,将大屏分为两个小屏,独立显示。在实现这个需求的时候使用了虚拟屏来实现小屏。为了过渡效果的平滑,需要做一些切换动画,其中一个点是要抓取虚拟屏的screenshot。

刚开始我使用了SurfaceControl.screenshot方法:

    /**
     * Copy the current screen contents into the provided {@link Surface}
     *
     * @param display The display to take the screenshot of.
     * @param consumer The {@link Surface} to take the screenshot into.
     * @param width The desired width of the returned bitmap; the raw
     * screen will be scaled down to this size.
     * @param height The desired height of the returned bitmap; the raw
     * screen will be scaled down to this size.
     */
    public static void screenshot(IBinder display, Surface consumer,
            int width, int height) {
        screenshot(display, consumer, new Rect(), width, height, 0, 0, true, false);
    }

之所以要IBinder display参数,是因为我要获取虚拟屏的截屏,而不是default display的截屏,所以我用来SurfaceControl.getBuiltinDisplay(int displayId)的方式获取display token,结果是screenshot一直获取的是黑屏,有点疑惑,因为虚拟屏的确是有显示的,不是黑色的。后面我又用screencap -p -d 3 /data/d3.png 获取截屏,发现还是黑色的,这样看来很可能是screenshot出了问题,跟到surfaceflinger里面看了一下,发现surfaceflinger不支持virtualdisplay的截屏,builtinDisplay中根本不包含virtual display,看来这个方法不行。

想来想去,我能拿到创建virtualdisplay的surface,能不能直接从这个surface得到bitmap呢?

 /**
     * Requests a copy of the pixels from a {@link Surface} to be copied into
     * a provided {@link Bitmap}.
     *
     * The contents of the source will be scaled to fit exactly inside the bitmap.
     * The pixel format of the source buffer will be converted, as part of the copy,
     * to fit the the bitmap's {@link Bitmap.Config}. The most recently queued buffer
     * in the Surface will be used as the source of the copy.
     *
     * @param source The source from which to copy
     * @param dest The destination of the copy. The source will be scaled to
     * match the width, height, and format of this bitmap.
     * @param listener Callback for when the pixel copy request completes
     * @param listenerThread The callback will be invoked on this Handler when
     * the copy is finished.
     */
    public static void request(@NonNull Surface source, @NonNull Bitmap dest,
            @NonNull OnPixelCopyFinishedListener listener, @NonNull Handler listenerThread) {
        request(source, null, dest, listener, listenerThread);
    }

  

看上去是可行的.

  

猜你喜欢

转载自www.cnblogs.com/wlffangfang/p/12951042.html