Android: take a screenshot of a view


There are some different ways to take a screenshot of a view. Here some code snippets ready to use in your app. The basic concept consists in render the content of the view into a bitmap.



The first easy way is to use the draw() function call as below:

Bitmap viewBmp = Bitmap.createBitmap(myView.getWidth(), myView.getHeight(), Config.ARGB_8888);
viewBmp.setDensity(myView.getResources().getDisplayMetrics().densityDpi);
Canvas canvas = new Canvas(viewBmp);
myView.draw(canvas);

Second way is to use the getDrawingCache() function call as follow:

myView.setDrawingCacheEnabled(true);
myView.buildDrawingCache();
Bitmap viewBmp = Bitmap.createBitmap(myView.getDrawingCache());
myView.setDrawingCacheEnabled(false);

This second example required some additional notes:

- If you look inside the android code you'll see this second method basically use the first draw() example internally than there is not big differences. Using this second way you simply don't have to create bitmap and canvas yourself.
- The function getDrawingCache() return the screenshot bitmap than, in theory, would not be necessary to create a new bitmap from this original one using createBitmap(). The problem is the bitmap object returned will be "reused" by the system to make new updated screenshot automatically than you can not "trust" the content will remain always the same. The easy solution for the problem is to make a copy of current image as the code show.
- You don't need to continuously call setDrawingCacheEnabled() with true and false param for each capture. Here is reported as example for give a full sequence but if you need to make continuous capture you can simply call setDrawingCacheEnabled(true) during activity start and capture updated screenshot using getDrawingCache() only.
- Enable drawing cache mean "force" the view to paint inside a bitmap and this can introduce some loss of performance, keep in mind this problem just in case.

Please note these codes will work only if myView is currently inside some Layout and visible. This because the Layout automatically assign a size to the view based to the params you set during design. In case your view is offscreen and not assigned to any layout you have to assign dimension since a new view have null size at beginning. You can assign the dimension using the following code:
myView.measure(MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED), MeasureSpec.makeMeasureSpec(0, MeasureSpec.UNSPECIFIED));
FrameLayout.LayoutParams params = (android.widget.FrameLayout.LayoutParams) myView.getLayoutParams();
params.width  = width;
params.height = height;
myView.setLayoutParams(params);

Comments

Popular posts from this blog

Access GPIO from Linux user space

Android: adb push and read-only file system error

Tree in SQL database: The Nested Set Model