I'm trying to take a screenshot of the contents of a LinearLayout. The layout contains a scrollview that can be of variable height/width. This code works fine when the layout is not too big (i.e. you don't need to scroll very much off screen to see everything):
View v1 = (LinearLayout)theLayout;
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
However, if the LinearLayout that I'm trying to capture is large, then the application crashes with a null pointer on v1.getDrawingCache().
There is an error in logcat:
05-11 13:16:20.999: W/View(17218): View too large to fit into drawing
cache, needs 4784400 bytes, only 3932160 available
How can I properly take a screenshot of this layout? Is there another way to go about it that doesn't use so much memory?
Here's what ended up working for me to capture a large off-screen view in it's entirety:
public static Bitmap loadBitmapFromView(View v)
{
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
It's similar to the answer here, except that I use the view's width/height to create the bitmap
As the original question is talking about a ScrollView I just though I would add the following for anyone that was having problems getting the full height. To get the height of the ScrollView, the v.getHeight doesn't work, you need to use:
v.getChildAt(0).getHeight()
so the full thing would be:
ScrollView scrollView = (ScrollView) result.findViewById(R.id.ScrlView);
loadBitmapFromView(scrollView);
public static Bitmap loadBitmapFromView(View v)
{
int height = v.getChildAt(0).getHeight()
int width = v.getWidth()
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
Just using v.getHeight just gets the screen height, not the full height of the ScrollView.
Related
I want to get a screenshot in a scrollable view (ViewPager), but I´m only getting a image from what is in the screen.
I have a Viewpager with two childrens
android.support.v4.view.PagerTitleStrip
NoSaveStateFrameLayout
I´m using this code to get the screenshot
private Bitmap screenShot(View view) {
Bitmap capture = null;
view.setDrawingCacheEnabled(true);
capture = Bitmap.createBitmap(view.getDrawingCache());
view.setDrawingCacheEnabled(false);
return capture;
}
I need to capture the hole content, the scrollable content that is not in screen yet.
you can create bitmap of any view by following method
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
simply use above with your parent view and create bitmap of entire activity
I have found how to fix that here
You have to get the child height in Scrollable View.
While trying to make a screen shot of a custom view,I got the IllegalArgumentException : width and height must be >0. Here is what I wrote :
bitmap = loadBitmapFromView(v1);//v1 the custom view I want to picture.
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getLayoutParams().width, v.getLayoutParams().height);
v.draw(c);
return b;
}
The line in which there is the exception : Bitmap b = Bitmap.createBitmap( v.getLayoutParams().width, v.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Of course the screen shot code is executed after the view is showed,on the next_act button code
The width and height of LayoutParams can be a constant such as FILL_PARENT, and they are negative numbers.
To get the view's measured dimensions you can use:
v.getMeasuredWidth() and v.getMeasuredHeight()
However, it depends on what you're after, and whether the view has been measured.
It would probably make more sense to wait until the view has been drawn, before taking the screenshot ;-) But you'd need to explain more about your use case.
I have researched to find solution to take a snapshot of current activity and I found 2 solutions to taking a snapshot, but all of them can't help me get right thing which I want.
My activity use camera, and I show 3D object in that layout (same as AR, but not use marker, just draw 3D object in camera frame).
So when I use found solutions, I just get Parent layout (RelativeLayout which I use to keep both camera and 3D object) with some other objects (some button), that bitmap same as physical design screen of XML file.
I used this solution to get snapshot:
private Bitmap takeScreenShot(Activity activity)
{
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap b1 = 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(b1, 0, statusBarHeight, width, height - statusBarHeight);
view.destroyDrawingCache();
return b;
}
and this solution:
public Bitmap snap() {
Bitmap bitmap = Bitmap.createBitmap(this.view.getWidth(), this.view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
But I got same result.
Please help me to find good solution to resolve this problem.
Thanks.
I am creating the bitmap from a linearlayout with the following code
public static Bitmap loadBitmapFromView(View v ) {
//Bitmap b = Bitmap.createBitmap( v.getLayoutParams.width, v.getLayoutParams.height, Bitmap.Config.ARGB_8888);
Bitmap b = Bitmap.createBitmap( v.getLayoutParams.width, v.getLayoutParams.height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.draw(c);
return b;
}
but i can not see the views in it
all i can see is a big grey screen
have tried the answer at this question also Android Problems Converting ViewGroup with Children into Bitmap but still not working
My view is being inflated from xml
and when i use the code mentioned above i get force close for null pointer exception
and if i mention the width and height to some number like 200 , 200 then i am able to see the grey background only not the view in it.
You need to measure the view before layout like
v.measure(
MeasureSpec.makeMeasureSpec(v.getLayoutParams().width,MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(v.getLayoutParams().height, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight()
,Bitmap.Config.RGB_565);
Canvas c = new Canvas(b);
v.draw(c);
I have been trying to create a bit map of a list view, where the entire list view is not visible on the screen. I am using
Bitmap mBitmap = fullView.getDrawingCache();
to create bitmap. It works ok for the part of list view that is visible on the screen but, not for the part that isn't.I would like to know if a bitmap of a list view can be created without having to display it completely on the screen. All suggestions and or solutions are appreciated.
As android only draws what is visible, may idea would be to take bitmaps in pieces and then group the bitmaps into a single one. You could first get the bitmap of first n items. Then use the scrollTo method to scroll beyond the previous n items and get the bitmap for the next n items. This way you can get bitmap of the whole list view.
Try using this method. Hack here is calling the layout and measure method of the view yourself.
public Bitmap loadBitmapFromView(View v) {
v.setLayoutParams(new ViewGroup.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT,
RelativeLayout.LayoutParams.WRAP_CONTENT));
v.measure(View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED),
View.MeasureSpec.makeMeasureSpec(0, View.MeasureSpec.UNSPECIFIED));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap bitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
v.layout(v.getLeft(), v.getTop(), v.getRight(), v.getBottom());
v.draw(c);
return bitmap;
}
Pass the view in this method like
LayoutInflater inflater = (LayoutInflater) this.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
View inflatedFrame = inflater.inflate(R.layout.my_view, null);
Bitmap bitmap = loadBitmapFromView(inflatedFrame.findViewById(R.id.id_of_your_view_in_layout));