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.
Related
I'm trying to save a screenshot of my current Activity, but not the whole view, just part of it.
In my case:
My activity
At the attached image, i want to save a bitmap constructed from views B,C & D.
B is a linear layout, C is a pure bitmap, and D is a relative layout.
To my understanding, one way to go is creating a canvas, add all 'elements' into it and finally have the custom bitmap desired.
I'm having trouble with the following code:
iViewBHeight= viewB.getHeight();
// Prepare empty bitmap as output
Bitmap result = Bitmap.createBitmap(bitmapC.getWidth(),bitmapC.getHeight() + iViewBHeight, Config.ARGB_8888);
// Flush source image into canvas
Canvas canvas = new Canvas(result);
// Draw bitmap C to canvas 'under' view B
canvas.drawBitmap(bitmapC, 0, iViewBHeight, null);
// Draw view B to canvas
viewB.setDrawingCacheEnabled(true);
viewB.buildDrawingCache(true);
canvas.drawBitmap(Bitmap.createBitmap(viewB.getDrawingCache()), 0, 0, null);
viewB.setDrawingCacheEnabled(false);
// Desired bitmap is at 'result'
The result is that bitmap C is drawn Ok, but view B is too large and extends the bitmap.
I didn't try adding view D..
Can anyone help me? Maybe there are better ways achieving my goal?
Thanks!
I think the easiest way to accomplish that is to grab a screenshot of the Activity's entire content, then crop off the A View. The Canvas#drawBitmap(Bitmap bmp, Rect src, Rect dest, Paint pnt) overload does this easily. The Rect src describes section of the source Bitmap you're copying, while dest is the section of the destination Bitmap that the source will be drawn in. (NB: the Rects don't have to be the same size.)
I believe the following method should do what you want, if I'm following you correctly.
private Bitmap capture()
{
View actContent = findViewById(android.R.id.content);
Bitmap result = Bitmap.createBitmap(actContent.getWidth(),
actContent.getHeight() - viewA.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(result);
actContent.setDrawingCacheEnabled(true);
Rect src = new Rect(0, viewA.getHeight(), actContent.getWidth(), actContent.getHeight());
Rect dest = new Rect(0, 0, result.getWidth(), result.getHeight());
canvas.drawBitmap(actContent.getDrawingCache(), src, dest, null);
actContent.setDrawingCacheEnabled(false);
return result;
}
I'm trying to implement a system whereby if an uncaught exception occurs, my exception handler will take a screenshot of the activity, to be saved and sent off as part of a bug report. Is this even possible in Android? I'm passing the activity to the exception handler in the constructor, but every attempt I've used so far to get the screenshot has returned null.
I've tried the following:
Attempt One:
private Bitmap screenshot() {
View view = activity.getWindow().getDecorView(); //also tried getDecorView().getRootView()
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
view.setDrawingCacheEnabled(true);
view.buildDrawingCache(true);
Bitmap image = view.getDrawingCache();
Rect windowbounds = new Rect();
view.getWindowVisibleDisplayFrame(windowbounds);
int width = activity.getWindowManager().getDefaultDisplay().getWidth();
int height = activity.getWindowManager().getDefaultDisplay().getHeight();
Bitmap secondaryBitmap = Bitmap.createBitmap(image, 0, 0, width, height);
view.destroyDrawingCache();
return secondaryBitmap;
}
Attempt Two:
private Bitmap screenshot2()
{
View view = activity.getWindow().getDecorView(); //also tried getDecorView().getRootView()
view.setLayerType(View.LAYER_TYPE_SOFTWARE, null);
Bitmap viewBmp = Bitmap.createBitmap(view.getWidth(),view.getHeight(),
Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(viewBmp);
view.draw(canvas);
return viewBmp;
}
In attempt #1 the view.getDrawingCache() returns null, and in attempt #2 Bitmap.createBitmap returns null.
Any Android developers have any idea on how to take a screenshot in the UncaughtExceptionHandler?
You do not want:
Bitmap viewBmp = Bitmap.createBitmap(view.getLayoutParams().width, view.getLayoutParams().height,
Bitmap.Config.ARGB_8888);
The LayoutParams does not normally have the actual width and height. Often it has negative values, indicating wrap_content or match_parent.
Instead, try:
Bitmap viewBmp = Bitmap.createBitmap(view.getWidth(), view.getHeight(),
Bitmap.Config.ARGB_8888);
or something along those lines. You want the actual width and height of the container, not the width and height requested by its LayoutParams.
Is there possible to overlay an image on camera preview butt that image for example a coin should look like an original view, as I will move my camera it will remains in its place just like real objects as seen in camera.
I have done with overlaying a static image on camera preview but that's not my requirement.
please suggest.
thanks.
to overlay an image up to another image use this method.
public Bitmap overlayChange(Bitmap all, Bitmap scaledBorder) {
final int width = change.getWidth();
final int height = change.getHeight();
all = Bitmap.createScaledBitmap(change, width, height, true);
Bitmap mutableBitmap = all.copy(Bitmap.Config.ARGB_8888, true);
Canvas canvas = new Canvas(mutableBitmap);
scaledBorder = Bitmap.createScaledBitmap(border, width, height, true);
canvas.drawBitmap(scaledBorder, 0, 0, null);
return mutableBitmap;
}
and to use it simple
yourBitmap = overlayChange(yourBitmap , YourOtherBitmap);
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.
For my application, i have used pinch zoom feature by adapting from the tutorial and creating a custom view http://www.zdnet.com/blog/burnette/how-to-use-multi-touch-in-android-2-part-6-implementing-the-pinch-zoom-gesture/1847
Right now i'm working on capturing the zoomed image as bitmap.
Partially I was able to get the bitmap by making use of
setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(finalView.getDrawingCache());
setDrawingCacheEnabled(false);
Using this approach, I'm getting both the zoomed image and the screen background.
Is there any way to capture only the zoomed image as a bitmap?
Try
setDrawingCacheEnabled(false)
finalView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(finalView.getDrawingCache());
finalView.setDrawingCacheEnabled(false);
After having searched a lot, I found a 'Temporary' solution in the same Community & also thanks for the code from 'weakwire' provided in the same post.
Getting coordinates and width/height from a matrix
Idea is simple, all i have do is remove the background screen from the scaled image by cropping. Code is bit lengthy, but worked for me.
First get the Original Bitmap size
float imgWidth = imgBitmap.getWidth()
float imgHeight = imgBitmap.getHeight()
Obtain the matrix ( pinch zoom feature used in my application uses matrix 'trick') values, used to scale the image and get the scaledWidth & scaledHeight of the original image.
float[] values = new float[9];
matrix.getValues(values);
float globalX = values[2];
float globalY = values[5];
float scaledWidth = values[0]*imgWidth;
float scaledHeight = values[4]*imgHeight;
// If zoomed Image gets out of screen, I'm trying to crop the image available in the screen by considering image from (0,0)
if(globalX<0)
globalX = 0;
if(globalY<0)
globalY = 0;
Finally capture the View and crop the background
In my case ("finalView" is the custom View name, where pinch zooming happens)
setDrawingCacheEnabled(false);
destroyDrawingCache();
finalView.setDrawingCacheEnabled(true);
Bitmap bm = Bitmap.createBitmap(finalView.getDrawingCache());
finalView.setDrawingCacheEnabled(false);
//Final Image Width & Height
int finalWidth = Math.min((int)width,(int)finalView.getWidth());
int finalHeight = Math.min((int)height,(int)finalView.getHeight());
// crop to get the scaled image
Bitmap finalBitmap = Bitmap.createBitmap(bm, (int)globalX, (int)globalY, finalWidth ,finalHeight);
Though this is a temporary solution, it works for me. If there is any alternate solution, please post it.
This original answer here, just replace the setting background part. Hopefully it helps
public static Bitmap getBitmapFromView(View view) {
if (view == null) return null;
//Define a bitmap with the same size as the view
Bitmap returnedBitmap = Bitmap.createBitmap(view.getWidth(), view.getHeight(), Bitmap.Config.ARGB_8888);
//Bind a canvas to it
Canvas canvas = new Canvas(returnedBitmap);
// draw white background on the canvas
canvas.drawColor(Color.WHITE);
// draw the view on the canvas
view.draw(canvas);
//return the bitmap
return returnedBitmap;
}