如何通过代码而不是程序来截取手机屏幕的选定区域的截图?
当前回答
我的解决方案是:
public static Bitmap loadBitmapFromView(Context context, View v) {
DisplayMetrics dm = context.getResources().getDisplayMetrics();
v.measure(MeasureSpec.makeMeasureSpec(dm.widthPixels, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(dm.heightPixels, MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
Bitmap returnedBitmap = Bitmap.createBitmap(v.getMeasuredWidth(),
v.getMeasuredHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(returnedBitmap);
v.draw(c);
return returnedBitmap;
}
and
public void takeScreen() {
Bitmap bitmap = ImageUtils.loadBitmapFromView(this, view); //get Bitmap from the view
String mPath = Environment.getExternalStorageDirectory() + File.separator + "screen_" + System.currentTimeMillis() + ".jpeg";
File imageFile = new File(mPath);
OutputStream fout = null;
try {
fout = new FileOutputStream(imageFile);
bitmap.compress(Bitmap.CompressFormat.JPEG, 90, fout);
fout.flush();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
fout.close();
}
}
图像保存在外部存储文件夹中。
其他回答
这个方法不需要root权限,也不需要大量编码。
在adb shell上使用以下命令可以截屏。
input keyevent 120
这个命令不需要任何root权限,所以你也可以从android应用程序的java代码执行。
Process process;
process = Runtime.getRuntime().exec("input keyevent 120");
更多关于android中的keyevent代码,请参阅http://developer.android.com/reference/android/view/KeyEvent.html
这里我们用了。KEYCODE_SYSRQ,它的值是120,用于系统请求/打印屏幕键。
如CJBS所说,输出的图片将保存在/sdcard/Pictures/Screenshots
对于那些想要捕获GLSurfaceView的人,getDrawingCache或绘制到画布方法将不起作用。
在帧呈现之后,您必须读取OpenGL帧缓冲区的内容。这里有一个很好的答案
在android中截取视图的截图。
public static Bitmap getViewBitmap(View v) {
v.clearFocus();
v.setPressed(false);
boolean willNotCache = v.willNotCacheDrawing();
v.setWillNotCacheDrawing(false);
int color = v.getDrawingCacheBackgroundColor();
v.setDrawingCacheBackgroundColor(0);
if (color != 0) {
v.destroyDrawingCache();
}
v.buildDrawingCache();
Bitmap cacheBitmap = v.getDrawingCache();
if (cacheBitmap == null) {
return null;
}
Bitmap bitmap = Bitmap.createBitmap(cacheBitmap);
v.destroyDrawingCache();
v.setWillNotCacheDrawing(willNotCache);
v.setDrawingCacheBackgroundColor(color);
return bitmap;
}
你可以尝试这样做,
从布局或视图中获取位图缓存 首先你需要setDrawingCacheEnabled到一个布局(线性布局或相对布局,或视图)
然后
Bitmap bm = layout.getDrawingCache()
然后对位图做任何你想做的事情。要么将其转换为图像文件,要么将位图的uri发送到其他地方。
科特林
private fun screenShot() {
try {
val mPath: String = this.getExternalFilesDir(null).getAbsolutePath()
.toString() + "/temp" + ".png"
// create bitmap screenshot
val v1: View = getWindow().getDecorView().getRootView()
v1.isDrawingCacheEnabled = true
val bitmap = Bitmap.createBitmap(v1.drawingCache)
v1.isDrawingCacheEnabled = false
val imageFile = File(mPath)
val outputStream = FileOutputStream(imageFile)
val quality = 100
bitmap.compress(Bitmap.CompressFormat.PNG, quality, outputStream)
outputStream.flush()
outputStream.close()
//or you can share to test the method fast
val uriPath =
FileProvider.getUriForFile(this, getPackageName() + ".sharing.provider", imageFile)
val intent = Intent(Intent.ACTION_SEND)
intent.type = "image/*"
intent.clipData = ClipData.newRawUri("", uriPath)
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION or Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
intent.putExtra(Intent.EXTRA_STREAM, uriPath)
startActivity(Intent.createChooser(intent, "Sharing to..."))
} catch (e: Throwable) {
e.printStackTrace()
}
}
Java
private void screenShot() {
try {
String mPath = this.getExternalFilesDir(null).getAbsolutePath().toString() + "/temp" + ".png";
// create bitmap screenshot
View v1 = getWindow().getDecorView().getRootView();
v1.setDrawingCacheEnabled(true);
Bitmap bitmap = Bitmap.createBitmap(v1.getDrawingCache());
v1.setDrawingCacheEnabled(false);
File imageFile = new File(mPath);
FileOutputStream outputStream = new FileOutputStream(imageFile);
int quality = 100;
bitmap.compress(Bitmap.CompressFormat.PNG, quality, outputStream);
outputStream.flush();
outputStream.close();
//or you can share to test the method fast
Uri uriPath = FileProvider.getUriForFile(this, getPackageName() + ".sharing.provider", imageFile);
Intent intent = new Intent(Intent.ACTION_SEND);
intent.setType("image/*");
intent.setClipData(ClipData.newRawUri("", uriPath));
intent.addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
intent.putExtra(Intent.EXTRA_STREAM, uriPath);
startActivity(Intent.createChooser(intent, "Sharing to..."));
} catch (Throwable e) {
e.printStackTrace();
}
}
推荐文章
- 警告:API ' variable . getjavacompile()'已过时,已被' variable . getjavacompileprovider()'取代
- 安装APK时出现错误
- 碎片中的onCreateOptionsMenu
- TextView粗体通过XML文件?
- 如何使线性布局的孩子之间的空间?
- DSL元素android.dataBinding。enabled'已过时,已被'android.buildFeatures.dataBinding'取代
- ConstraintLayout:以编程方式更改约束
- PANIC: AVD系统路径损坏。检查ANDROID_SDK_ROOT值
- 如何生成字符串类型的buildConfigField
- Recyclerview不调用onCreateViewHolder
- Android API 21工具栏填充
- Android L中不支持操作栏导航模式
- 如何在TextView中添加一个子弹符号?
- PreferenceManager getDefaultSharedPreferences在Android Q中已弃用
- 在Android Studio中创建aar文件