安卓SurfaceView截屏

关于安卓SurfaceView截屏

2015.12.9号是一个值得记得日子,开始拖着背包从学校出来,挤上火车,做着接近30小时的硬座,来到了美丽的成都,那时候赵雷的<成都>还没火,‘走到玉林路的尽头 坐在小酒馆的门口 ‘,多么诗情画意的生活啊。来不及享受这安逸之都的生活,便匆匆的开始实习生涯。
时至今日,也已经毕业大半年了,也从实习生正式成了职场人。身边大神很多,公司也是藏龙卧虎,也感觉应该养成写作的习惯,一来可以总结一下,以便之后自己查看。同时,因为写作也会去查很多资料,也可以加深对问题的认识。最后,只是也是一种分享的过程,网上东西良莠不齐,能够对一些自己熟悉的领域写好,帮助别人也是一种快乐吧。总不至于自己每天在各种bug中享受暗无天日的生活吧,一度开始怀疑人生。找点有意义的事情做,总是好的。
下面来谈谈SurfaceView截屏的问题,SufaceView视图原理我就不再赘述,网上一搜大把,下面直接将贴代码吧。
1.root情况下,读取Framebuff上面的像素,通过像素得到Bitmap,再将Bitmap以图片形式输出。

private static final String DEVICE_NAME = "/dev/graphics/fb0";
@SuppressWarnings("deprecation")
    public static Bitmap acquireScreenshot(Context context) {
        WindowManager mWinManager = (WindowManager) context
                .getSystemService(Context.WINDOW_SERVICE);
        DisplayMetrics metrics = new DisplayMetrics();
        Display display = mWinManager.getDefaultDisplay();
        display.getMetrics(metrics);
        // 屏幕高
        int height = metrics.heightPixels;
        // 屏幕的宽
        int width = metrics.widthPixels;

        int pixelformat = display.getPixelFormat();
        PixelFormat localPixelFormat1 = new PixelFormat();
        PixelFormat.getPixelFormatInfo(pixelformat, localPixelFormat1);
        // 位深
        int deepth = localPixelFormat1.bytesPerPixel;

        byte[] arrayOfByte = new byte[height * width * deepth];
        try {
            // 读取设备缓存,获取屏幕图像流
            InputStream localInputStream = readAsRoot();
            DataInputStream localDataInputStream = new DataInputStream(
                    localInputStream);
            localDataInputStream.readFully(arrayOfByte);
            localInputStream.close();

            int[] tmpColor = new int[width * height];
            int r, g, b;
            for (int j = 0; j < width * height * deepth; j += deepth) {
                b = arrayOfByte[j] & 0xff;
                g = arrayOfByte[j + 1] & 0xff;
                r = arrayOfByte[j + 2] & 0xff;
                tmpColor[j / deepth] = (r << 16) | (g << 8) | b | (0xff000000);
            }
            // 构建bitmap
            Bitmap scrBitmap = Bitmap.createBitmap(tmpColor, width, height,
                    Bitmap.Config.ARGB_8888);
            return scrBitmap;

        } catch (Exception e) {
            Log.d(TAG, "#### 读取屏幕截图失败");
            e.printStackTrace();
        }
        return null;

    }
/**
     * @Title: readAsRoot
     * @Description: 以root权限读取屏幕截图
     * @throws Exception
     * @throws
     */
    public static InputStream readAsRoot() throws Exception {
        File deviceFile = new File(DEVICE_NAME);
        Process localProcess = Runtime.getRuntime().exec("su");
        String str = "cat " + deviceFile.getAbsolutePath() + "\n";
        localProcess.getOutputStream().write(str.getBytes());
        return localProcess.getInputStream();
    }

    //将读取的bitmap输出图片到SD卡上
public static void shoot(Activity activity, File filePath) {
        if (filePath == null) {
            return;
        }
        if (!filePath.getParentFile().exists()) {
            filePath.getParentFile().mkdirs();
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filePath);
            if (null != fos) {
                takeScreenShot(activity).compress(Bitmap.CompressFormat.PNG, 100, fos);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

2.非root 直接在SurfaceView中实时输出bitmap,然后将bitmap输出成图片保存下来。

    /**
     * 将实时bitmap输出到指定sd卡。
     */
    public void saveScreenshot() {
        if (ensureSDCardAccess()) {
            Bitmap bitmap = Bitmap.createBitmap(getWidth(), getHeight(), Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(bitmap);
            doDraw(1, canvas);
            File file = new File(mScreenshotPath + "/" + System.currentTimeMillis() + ".jpg");
            FileOutputStream fos;
            try {
                fos = new FileOutputStream(file);
                bitmap.compress(Bitmap.CompressFormat.JPEG, 100, fos);
                fos.close();
            } catch (FileNotFoundException e) {
                Log.e("xxx", "FileNotFoundException", e);
            } catch (IOException e) {
                Log.e("xxx", "IOEception", e);
            }
        }
    }

    /**
     * 
     * 指定路径文件是否存在
     */
    private boolean ensureSDCardAccess() {
        File file = new File(mScreenshotPath);
        if (file.exists()) {
            return true;
        } else if (file.mkdirs()) {
            return true;
        }
        return false;
    }

二.附上普通view截图方式。

public class ScreenShot {

    public static void shoot(Activity activity, File filePath) {
        if (filePath == null) {
            return;
        }
        if (!filePath.getParentFile().exists()) {
            filePath.getParentFile().mkdirs();
        }
        FileOutputStream fos = null;
        try {
            fos = new FileOutputStream(filePath);
            if (null != fos) {
                takeScreenShot(activity).compress(Bitmap.CompressFormat.PNG, 100, fos);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } finally {
            if (fos != null) {
                try {
                    fos.flush();
                    fos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    @SuppressWarnings("deprecation")
    private static Bitmap takeScreenShot(Activity activity) {
        View view = activity.getWindow().getDecorView();
        view.setDrawingCacheEnabled(true);
        view.buildDrawingCache();
        Bitmap bitmap = view.getDrawingCache();
        Rect frame = new Rect();
        activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
        int statusBarHeight = frame.top;

        int width = activity.getWindowManager().getDefaultDisplay().getWidth();
        int height = activity.getWindowManager().getDefaultDisplay()
                .getHeight();
        // 
        Bitmap b = Bitmap.createBitmap(bitmap, 0, statusBarHeight, width,
                height - statusBarHeight);
        view.destroyDrawingCache();
        return b;
    }

}
评论 20
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值