问题
I am working on an app, which uses the frontcamera to simulate a mirror for the person using the app. I have implemented a "Head-up-Display" which is in front of the cameraview and displays some stuff. This works fine at the moment. Now I'd like to implement a method to take a screenshot every 5s.
But how to take a screenshot? I tried one possible solution, but this just takes a screenshot of the HuD without the mirror, because I have to pass a view (v1) to this method:
// create bitmap screen capture
Bitmap b1;
View v1 = (RelativeLayout) findViewById(R.id.RelLayout);
v1.setDrawingCacheEnabled(true);
b1 = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
//mPreviewLayout.setDrawingCacheEnabled(true);
//mPreviewLayout.buildDrawingCache();
//Bitmap b1 = mPreviewLayout.getDrawingCache();
String path = Environment.getExternalStorageDirectory().toString();
FileOutputStream out = null;
try {
File file = new File(path, "brushGuide" + instructionCounter + ".jpg");
out = new FileOutputStream(file);
b1.compress(Bitmap.CompressFormat.PNG, 90, out);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
out.close();
} catch (Throwable ignore) {
}
}
My layout and the important code for this question is quite less:
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
android:id="@+id/RelLayout"
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center_horizontal" >
<FrameLayout
android:id="@+id/camPreview"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_centerHorizontal="true"
android:layout_centerVertical="true" >
</FrameLayout>
<ImageView android:id="@+id/imageView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="80dp"
android:layout_marginLeft="65dp"
></ImageView>
</RelativeLayout>
onCreate()
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// do we have a camera?
if (!getPackageManager()
.hasSystemFeature(PackageManager.FEATURE_CAMERA)) {
Toast.makeText(this,
"No camera feature on this device. App closing",
Toast.LENGTH_LONG).show();
}else{
mCameraId = findFirstFrontFacingCamera();
if (mCameraId >= 0) {
// Kamera wurde gefunden
mPreviewLayout = (FrameLayout) findViewById(R.id.camPreview);
mPreviewLayout.removeAllViews();
startCameraInLayout(mPreviewLayout, mCameraId);
}
}
}
Is even possible to just take a normal screenshot of the actual content of the devices display without rooting the device, and if yes: How?
Any help will be appreciated.
回答1:
I actually just did this the other day and it was a pain to get a screenshot of the entire Activity, while also making sure to remove the StatusBar from the image (as it will appear as a black rectangle in the drawing cache). This method will also allow you to overlay the returned image with some color (ie. fading)):
public static Bitmap getActivitySnapshot(Activity activity, boolean fade){
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
Bitmap bmap = view.getDrawingCache();
Rect statusBar = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(statusBar);
Bitmap snapshot = Bitmap.createBitmap(bmap, 0, statusBar.top, bmap.getWidth(), bmap.getHeight() - statusBar.top, null, true);
if(fade && snapshot != null){
Canvas canvas = new Canvas(snapshot);
Paint paint = new Paint();
paint.setColor(Color.parseColor("#88121212"));
canvas.drawRect(0, 0, snapshot.getWidth(), snapshot.getHeight(), paint);
}
view.setDrawingCacheEnabled(false);
return snapshot;
}
If you don't want the fading part, the important parts would just be:
public static Bitmap getActivitySnapshot(Activity activity){
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
Bitmap bmap = view.getDrawingCache();
Rect statusBar = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(statusBar);
Bitmap snapshot = Bitmap.createBitmap(bmap, 0, statusBar.top, bmap.getWidth(), bmap.getHeight() - statusBar.top, null, true);
view.setDrawingCacheEnabled(false);
return snapshot;
}
You may also want to catch the OutOfMemoryError that may be thrown when working with large Bitmaps.
回答2:
This code can help you.
/**
* @param v view to capture it may be any Layout
* @return
*/
public static Bitmap captureScreen(View v)
{
Bitmap bitmap = null;
try {
if(v!=null)
{
int width = v.getWidth();
int height = v.getHeight();
Bitmap screenshot = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
v.draw(new Canvas(screenshot));
}
} catch (Exception e)
{
Log.d("captureScreen", "Failed");
}
return bitmap;
}
回答3:
By screenshot, would a copy of your Root view help?
If so, you can use this:
public static Bitmap loadBitmapFromView(View view) {
Bitmap bitmap = Bitmap.createBitmap(view.getLayoutParams().width, view.getLayoutParams().height, Bitmap.Config.ARGB_8888);
Canvas canvas = new Canvas(bitmap);
view.layout(view.getLeft(), view.getTop(), view.getRight(), view.getBottom());
view.draw(canvas);
return bitmap;
}
Just pass your root view into this function and you can save the bitmap.
来源:https://stackoverflow.com/questions/23660932/take-screenshot