/** * Like {@link SurfaceControl#screenshot(int, int, int, int, boolean)} but includes all Surfaces * in the screenshot. * * @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. * @return Returns a Bitmap containing the screen contents, or null if an error occurs. Make sure * to call Bitmap.recycle() as soon as possible, once its content is not needed anymore. */ public static Bitmap screenshot(int width, int height) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot( displayToken, new Rect(), width, height, 0, 0, true, false, Surface.ROTATION_0); }
private boolean captureScreenshotTextureAndSetViewport() { if (!attachEglContext()) { return false; } try { if (!mTexNamesGenerated) { GLES10.glGenTextures(1, mTexNames, 0); if (checkGlErrors("glGenTextures")) { return false; } mTexNamesGenerated = true; } final SurfaceTexture st = new SurfaceTexture(mTexNames[0]); final Surface s = new Surface(st); try { SurfaceControl.screenshot( SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN), s); } finally { s.release(); } st.updateTexImage(); st.getTransformMatrix(mTexMatrix); // Set up texture coordinates for a quad. // We might need to change this if the texture ends up being // a different size from the display for some reason. mTexCoordBuffer.put(0, 0f); mTexCoordBuffer.put(1, 0f); mTexCoordBuffer.put(2, 0f); mTexCoordBuffer.put(3, 1f); mTexCoordBuffer.put(4, 1f); mTexCoordBuffer.put(5, 1f); mTexCoordBuffer.put(6, 1f); mTexCoordBuffer.put(7, 0f); // Set up our viewport. GLES10.glViewport(0, 0, mDisplayWidth, mDisplayHeight); GLES10.glMatrixMode(GLES10.GL_PROJECTION); GLES10.glLoadIdentity(); GLES10.glOrthof(0, mDisplayWidth, 0, mDisplayHeight, 0, 1); GLES10.glMatrixMode(GLES10.GL_MODELVIEW); GLES10.glLoadIdentity(); GLES10.glMatrixMode(GLES10.GL_TEXTURE); GLES10.glLoadIdentity(); GLES10.glLoadMatrixf(mTexMatrix, 0); } finally { detachEglContext(); } return true; }
/** * Copy the current screen contents into a bitmap and return it. * * <p>CAVEAT: Versions of screenshot that return a {@link Bitmap} can be extremely slow; avoid use * unless absolutely necessary; prefer the versions that use a {@link Surface} instead, such as * {@link SurfaceControl#screenshot(IBinder, Surface)}. * * @param sourceCrop The portion of the screen to capture into the Bitmap; caller may pass in 'new * Rect()' if no cropping is desired. * @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. * @param minLayer The lowest (bottom-most Z order) surface layer to include in the screenshot. * @param maxLayer The highest (top-most Z order) surface layer to include in the screenshot. * @param useIdentityTransform Replace whatever transformation (rotation, scaling, translation) * the surface layers are currently using with the identity transformation while taking the * screenshot. * @param rotation Apply a custom clockwise rotation to the screenshot, i.e. * Surface.ROTATION_0,90,180,270. Surfaceflinger will always take screenshots in its native * portrait orientation by default, so this is useful for returning screenshots that are * independent of device orientation. * @return Returns a Bitmap containing the screen contents, or null if an error occurs. Make sure * to call Bitmap.recycle() as soon as possible, once its content is not needed anymore. */ public static Bitmap screenshot( Rect sourceCrop, int width, int height, int minLayer, int maxLayer, boolean useIdentityTransform, int rotation) { // TODO: should take the display as a parameter IBinder displayToken = SurfaceControl.getBuiltInDisplay(SurfaceControl.BUILT_IN_DISPLAY_ID_MAIN); return nativeScreenshot( displayToken, sourceCrop, width, height, minLayer, maxLayer, false, useIdentityTransform, rotation); }