如何通过代码而不是程序来截取手机屏幕的选定区域的截图?
当前回答
这个问题的大多数答案使用Canvas绘图方法或绘图缓存方法。然而,View.setDrawingCache()方法在API 28中已弃用。目前,用于制作截图的推荐API是API 24提供的PixelCopy类(但接受Window参数的方法可从API 26 == Android 8.0 Oreo获得)。下面是一个检索位图的示例Kotlin代码:
@RequiresApi(Build.VERSION_CODES.O)
fun saveScreenshot(view: View) {
val window = (view.context as Activity).window
if (window != null) {
val bitmap = Bitmap.createBitmap(view.width, view.height, Bitmap.Config.ARGB_8888)
val locationOfViewInWindow = IntArray(2)
view.getLocationInWindow(locationOfViewInWindow)
try {
PixelCopy.request(window, Rect(locationOfViewInWindow[0], locationOfViewInWindow[1], locationOfViewInWindow[0] + view.width, locationOfViewInWindow[1] + view.height), bitmap, { copyResult ->
if (copyResult == PixelCopy.SUCCESS) {
saveBitmap(bitmap)
}
// possible to handle other result codes ...
}, Handler())
} catch (e: IllegalArgumentException) {
// PixelCopy may throw IllegalArgumentException, make sure to handle it
}
}
}
其他回答
捷径是
FrameLayout layDraw = (FrameLayout) findViewById(R.id.layDraw); /*Your root view to be part of screenshot*/
layDraw.buildDrawingCache();
Bitmap bmp = layDraw.getDrawingCache();
对于整页滚动截图
如果你想要捕捉一个完整的视图截图(其中包含一个滚动视图左右),那么在这个库中进行检查
https://github.com/peter1492/LongScreenshot
你所要做的就是导入Gradel,并创建一个bigscreen的对象
长截图=新BigScreenshot(这个,x, y);
当自动滚动屏幕视图组并在最后组装在一起时,将接收回调的屏幕截图位图。
get截图(Bitmap) {}
哪些可以保存到画廊或任何必要的用途,他们之后
科特林
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();
}
}
调用这个方法,传入你想要屏幕截图的最外层ViewGroup:
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;
}
如果你想从片段中截取截图,请遵循以下步骤:
Override onCreateView(): @Override public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) { // Inflate the layout for this fragment View view = inflater.inflate(R.layout.fragment_one, container, false); mView = view; } Logic for taking screenshot: button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { View view = mView.findViewById(R.id.scrollView1); shareScreenShotM(view, (NestedScrollView) view); } method shareScreenShotM)(): public void shareScreenShotM(View view, NestedScrollView scrollView){ bm = takeScreenShot(view,scrollView); //method to take screenshot File file = savePic(bm); // method to save screenshot in phone. } method takeScreenShot(): public Bitmap takeScreenShot(View u, NestedScrollView z){ u.setDrawingCacheEnabled(true); int totalHeight = z.getChildAt(0).getHeight(); int totalWidth = z.getChildAt(0).getWidth(); Log.d("yoheight",""+ totalHeight); Log.d("yowidth",""+ totalWidth); u.layout(0, 0, totalWidth, totalHeight); u.buildDrawingCache(); Bitmap b = Bitmap.createBitmap(u.getDrawingCache()); u.setDrawingCacheEnabled(false); u.destroyDrawingCache(); return b; } method savePic(): public static File savePic(Bitmap bm){ ByteArrayOutputStream bytes = new ByteArrayOutputStream(); bm.compress(Bitmap.CompressFormat.JPEG, 100, bytes); File sdCardDirectory = new File(Environment.getExternalStorageDirectory() + "/Foldername"); if (!sdCardDirectory.exists()) { sdCardDirectory.mkdirs(); } // File file = new File(dir, fileName); try { file = new File(sdCardDirectory, Calendar.getInstance() .getTimeInMillis() + ".jpg"); file.createNewFile(); new FileOutputStream(file).write(bytes.toByteArray()); Log.d("Fabsolute", "File Saved::--->" + file.getAbsolutePath()); Log.d("Sabsolute", "File Saved::--->" + sdCardDirectory.getAbsolutePath()); } catch (IOException e) { e.printStackTrace(); } return file; }
对于activity,您可以简单地使用View v1 = getWindow().getDecorView().getRootView();而不是mView
推荐文章
- 警告: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文件