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.
Related
I would like to ask help. I want to take screenshot. This is working, but ImageView rounded corners are not rounded on the taken screenshots (and elevation shadows missing too). I used
imageView.setClipToOutline(true);
to make this work on the phone, but on the screenshots they are rectangular.
These are my screenshot utils:
public class ScreenShotUtils {
public static Bitmap screenShotFromCanvas(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
public static Bitmap screenShotFromDrawingCache(View view) {
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(view.getDrawingCache());
view.destroyDrawingCache();
view.setDrawingCacheEnabled(false);
return bitmap;
}
Both method has the same result.
However i noticed, that if i turn the hardware acceleration off, the layout looks like the same as on the screenshots.
This is how it looks like after take screenshot:
This is how it should be:
Finally i solved my problem with MediaProjectionManager.
I want to take a picture of a view in Activity and share this picture.
First I use this method :
private Bitmap getShareViewShot() {
this.setDrawingCacheEnabled(true);
this.buildDrawingCache();
Bitmap bitmap = Bitmap.createBitmap(this.getDrawingCache(), 0, mSharePageRoot.getTop(), this.getWidth(), mSharePageRoot.getBottom());
this.setDrawingCacheEnabled(false);
return bitmap;
}
But if the view is in a ScrollView and the view has scrolled outside the screen, this method can't get a whole picture of this view.
So I change this method to below :
private Bitmap getShareViewShot() {
Bitmap bitmap = Bitmap.createBitmap(mSharePageRoot.getWidth(), mSharePageRoot.getHeight(),
Bitmap.Config.ARGB_8888);
mSharePageRoot.layout(0, 0, mSharePageRoot.getLayoutParams().width, mSharePageRoot.getLayoutParams().height);
final Canvas canvas = new Canvas(bitmap);
mSharePageRoot.draw(canvas);
return bitmap;
}
But another question comes: this view has no backgroud, so the picture I get has a black backgroud.In my code ,the Activity have a network image as the backgroud, so this means this method can't get the backgroud of the activity.
Please forgive me for my bad English.
Is there any other method ? thanks.
Yes, there is another method. There is a library by google called ASL(Android screenshot library). It's pretty simple.
https://code.google.com/archive/p/android-screenshot-library/wikis/DeveloperGuide.wiki
You can draw background by canvas, like this:
private Bitmap getShareViewShot() {
Bitmap bitmap = Bitmap.createBitmap(mSharePageRoot.getWidth(), mSharePageRoot.getHeight(),
Bitmap.Config.ARGB_8888);
mSharePageRoot.layout(0, 0, mSharePageRoot.getLayoutParams().width, mSharePageRoot.getLayoutParams().height);
final Canvas canvas = new Canvas(bitmap);
// the bitmap will have a white background
canvas.drawColor(0xffffffff);
mSharePageRoot.draw(canvas);
return bitmap;
}
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.
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 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));