Take proper screenshot - android

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.

Related

Create a rotation animation with a Drawable in SurfaceView

I have a Drawable (Vector) and I want to animate it rotating like a wheel. How would I go about this problem?
This is the only question I could find similar to my problem but the issue is the answer doesn't apply to VectorDrawables: Animating and rotating an image in a Surface View
I don't have any code to show because I don't even know where to start. I need some guidance.
You can convert VectorDrawable to Bitmap and than use solution from link.
private Bitmap getBitmap(VectorDrawable vectorDrawable) {
Bitmap bitmap = Bitmap.createBitmap(vectorDrawable.getIntrinsicWidth(),
vectorDrawable.getIntrinsicHeight(), Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
vectorDrawable.setBounds(0, 0, canvas.getWidth(), canvas.getHeight());
vectorDrawable.draw(canvas);
return bitmap;
}

How to take a screenshort of a view on android?

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;
}

Create widget with customview

I'd like to use several CustomViews in my appwidget and thus want to create a bitmap out of every CustomView.
So i tried that with
Bitmap customBitmap = customView.getDrawingCache(true);
remoteViews.setImageViewBitmap(R.id.imageView1, customBitmap );
but it doesn't work at all.
Are there any suggestions?
yes, it is drawn on a canvas
I would do something like this:
public Bitmap createCustomView(){
Bitmap bitmap = Bitmap.createBitmap(BITMAP_WIDTH, BITMAP_HEIGHT, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
// draw on the canvas:
// ...
return bitmap;
}
and then set the Bitmap to the ImageView:
remoteViews.setImageViewBitmap(R.id.imageView1, createCustomView() );

How I use the image of a screenshot?

I want to use the code of this link: How to take a screenshot and share it programmatically to take screenshots of my application. But I want the picture which is produced to use it to change my background, like this Layout.setBackgroundResource(resid).
How I can do this?
Where I will find the image's path to use it to change Background?
First you need the view you want a screen shot of:
View anyView = findViewById(R.id.anyView);
Then use this method to take a screenshot:
public Bitmap screenShot(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getWidth(),
view.getHeight(), Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.draw(canvas);
return bitmap;
}
like this:
Bitmap screenshot = screenShot(anyView);
Bitmaps can't be set as a background image so lets convert it to a drawable:
Drawable drawableScreenshot = new BitmapDrawable(getResources(), screenshot);
Now set it to be the View background:
anyView.setBackgroundDrawable(drawableScreenshot);

Create bitmap from view makes view disappear, how to get view canvas?

I found two ways of creating a Bitmap from a view. But once I do that, the view disappears and I can't use it anymore. How can I redraw the view after generating my bitmap?
1st:
public static Bitmap getBitmapFromView(View view) {
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(),Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable =view.getBackground();
if (bgDrawable!=null)
bgDrawable.draw(canvas);
else
canvas.drawColor(Color.WHITE);
view.draw(canvas);
return returnedBitmap;
}
2nd:
Bitmap viewCapture = null;
theViewYouWantToCapture.setDrawingCacheEnabled(true);
viewCapture = Bitmap.createBitmap(theViewYouWantToCapture.getDrawingCache());
theViewYouWantToCapture.setDrawingCacheEnabled(false);
EDIT
So, I think I understand what happens on the first one, we are basically removing the view from it's original canvas and drawing it somewhere else associated with that bitmap. Can somehow we store the original canvas and then set the view to be redrawn there?
Sorry, I'm not immensely knowledgeable on this. But I use the following code:
public Bitmap getBitmapFromView(View view, int width, int height) {
Bitmap returnedBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(returnedBitmap);
Drawable bgDrawable = view.getBackground();
if (view==mainPage.boardView) {
canvas.drawColor(BoardView.BOARD_BG_COLOR);
} else if (bgDrawable!=null) {
bgDrawable.draw(canvas);
} else {
canvas.drawColor(Color.WHITE);
}
view.measure(MeasureSpec.makeMeasureSpec(width, MeasureSpec.EXACTLY), MeasureSpec.makeMeasureSpec(height, MeasureSpec.EXACTLY));
view.layout(0, 0, width, height);
view.draw(canvas);
return returnedBitmap;
}
which is so similar to yours I suspect we copy&edited from the same place.
I have no trouble with the view disappearing from the original drawing tree. Mine is called for ViewGroups rather than plain Views.
Try this.
Getting the bitmap:
// Prepping.
boolean oldWillNotCacheDrawing = view.willNotCacheDrawing();
view.setWillNotCacheDrawing(false);
view.setDrawingCacheEnabled(true);
// Getting the bitmap
Bitmap bmp = view.getDrawingCache();
And make sure to reset the view back to its old self.
view.destroyDrawingCache();
view.setDrawingCacheEnabled(false);
view.setWillNotCacheDrawing(oldWillNotCacheDrawing);
return bmp;
Guy's answer works when the View has not yet been laid out in a parent view.
If the view already has been measured and laid out in a parent-view, Guy's answer may screw up your Activity's layout.
If the view hasn't yet been measured and laid out, Guy's answer works fine.
My answer would work after the View has been laid out and it won't screw up the Activity's layout since it doesn't measure and layout the View again.

Categories

Resources