Android 拍摄整个视图的屏幕截图
我已经构建了一个表,它基本上是由Android 拍摄整个视图的屏幕截图,android,screenshot,Android,Screenshot,我已经构建了一个表,它基本上是由水平滚动视图在滚动视图中完成的。我让用户可以编辑字段 现在我想在屏幕上保存表格,jpg、png、pdf或其他任何格式 问题是——桌子几乎总是比屏幕大 有没有办法制作整个ScrollView布局的屏幕截图?如果没有,您认为什么可以完成这项工作?您可能可以使用视图的图形缓存,但我不确定这是否会保存整个视图,或者只是保存渲染到屏幕上的内容 我建议您在StackOverflow上四处寻找类似的问题,以前很可能有人问过类似的问题。事实上,我找到了答案: public sta
水平滚动视图
在滚动视图
中完成的。我让用户可以编辑字段
现在我想在屏幕上保存表格,jpg、png、pdf或其他任何格式
问题是——桌子几乎总是比屏幕大
有没有办法制作整个
ScrollView
布局的屏幕截图?如果没有,您认为什么可以完成这项工作?您可能可以使用视图的图形缓存,但我不确定这是否会保存整个视图,或者只是保存渲染到屏幕上的内容
我建议您在StackOverflow上四处寻找类似的问题,以前很可能有人问过类似的问题。事实上,我找到了答案:
public static Bitmap loadBitmapFromView(View v) {
Bitmap b = Bitmap.createBitmap(v.getWidth() , v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
试试这个对我来说很好
TableLayout tabLayout = (TableLayout) findViewById(R.id.allview);
if (tabLayout != null) {
Bitmap image = Bitmap.createBitmap(tabLayout.getWidth(),
tabLayout.getHeight(), Config.ARGB_8888);
Canvas b = new Canvas(image);
tabLayout.draw(b);
}
不可能为尚未呈现的内容(如ScrollView的屏幕外部分)制作屏幕截图。但是,您可以制作多个屏幕截图,在每个截图之间滚动内容,然后加入图像。以下是一个可以为您实现自动化的工具:
免责声明:我是这个工具的作者,它是由。欢迎功能请求。您可以向视图传递基于位图对象构建的画布的新实例 试一试
Bitmap b = Bitmap.createBitmap(targetView.getWidth(),
targetView.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
targetView.draw(c);
BitmapDrawable d = new BitmapDrawable(getResources(), b);
canvasView.setBackgroundDrawable(d);`
它实际上为我做了这项工作。在我的情况下,使用@softwaresupply-answer会导致问题,我的视图被重新绘制并变得完全白色。有一个更简单的解决方案可以获得屏幕截图,您甚至不需要提供宽度和高度作为参数。
ScrollView iv = (ScrollView) findViewById(R.id.scrollView);
Bitmap bitmap = Bitmap.createBitmap(
iv.getChildAt(0).getWidth(),
iv.getChildAt(0).getHeight(),
Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(bitmap);
iv.getChildAt(0).draw(c);
// Do whatever you want with your bitmap
saveBitmap(bitmap);
使用图形缓存
public static Bitmap loadBitmapFromView(View v) {
Bitmap bitmap;
v.setDrawingCacheEnabled(true);
bitmap = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false);
return bitmap;
}
//设置按钮单击侦听器
share = (Button)findViewById(R.id.share);
share.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Bitmap bitmap = takeScreenshot();
saveBitmap(bitmap);
}
});
//然后您必须创建两个方法
public Bitmap takeScreenshot() {
View rootView = findViewById(android.R.id.content).getRootView();
rootView.setDrawingCacheEnabled(true);
return rootView.getDrawingCache();
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File(Environment.getExternalStorageDirectory() + "/screenshot.png");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
} catch (FileNotFoundException e) {
Log.e("GREC", e.getMessage(), e);
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
将此代码添加到应用程序后,运行应用程序并检查您的本地存储,您已经创建了整个页面的屏幕截图。这项工作对我来说很有用,希望对您也有帮助
public static Bitmap getBitmapByView(ScrollView scrollView) {
int h = 0;
Bitmap bitmap = null;
//get the actual height of scrollview
for (int i = 0; i < scrollView.getChildCount(); i++) {
h += scrollView.getChildAt(i).getHeight();
scrollView.getChildAt(i).setBackgroundResource(R.color.white);
}
// create bitmap with target size
bitmap = Bitmap.createBitmap(scrollView.getWidth(), h,
Bitmap.Config.ARGB_8888);
final Canvas canvas = new Canvas(bitmap);
scrollView.draw(canvas);
FileOutputStream out = null;
try {
out = new FileOutputStream("/sdcard/screen_test.png");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
try {
if (null != out) {
bitmap.compress(Bitmap.CompressFormat.PNG, 100, out);
out.flush();
out.close();
}
} catch (IOException e) {
// TODO: handle exception
}
return bitmap;
}
公共静态位图getBitmapByView(ScrollView ScrollView){
int h=0;
位图=空;
//获取scrollview的实际高度
对于(int i=0;i
从这里下载源代码()
活动\u main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:background="#efefef"
android:orientation="vertical">
<Button
android:id="@+id/btn_screenshot"
android:layout_width="match_parent"
android:layout_height="50dp"
android:layout_margin="10dp"
android:text="Take ScreenShot"/>
<ScrollView
android:id="@+id/scrollView"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginBottom="10dp"
android:background="#ffffff">
<LinearLayout
android:id="@+id/ll_linear"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginLeft="10dp"
android:layout_marginRight="10dp"
android:orientation="vertical">
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="@drawable/image2"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="@drawable/image3"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="@drawable/image5"/>
<ImageView
android:layout_width="match_parent"
android:layout_height="200dp"
android:layout_gravity="center"
android:layout_marginTop="10dp"
android:scaleType="fitXY"
android:src="@drawable/image6"/>
</LinearLayout>
</ScrollView>
</LinearLayout>
package deepshikha.com.screenshot;
import android.Manifest;
import android.content.Intent;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.os.Bundle;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.LinearLayout;
import android.widget.ScrollView;
import android.widget.Toast;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
public class MainActivity extends AppCompatActivity {
Button btn_screenshot;
ScrollView scrollView;
LinearLayout ll_linear;
public static int REQUEST_PERMISSIONS = 1;
boolean boolean_permission;
boolean boolean_save;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
init();
fn_permission();
}
private void init() {
btn_screenshot = findViewById(R.id.btn_screenshot);
scrollView = findViewById(R.id.scrollView);
ll_linear = findViewById(R.id.ll_linear);
btn_screenshot.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View view) {
if (boolean_save) {
Intent intent = new Intent(getApplicationContext(), Screenshot.class);
startActivity(intent);
} else {
if (boolean_permission) {
Bitmap bitmap1 = loadBitmapFromView(ll_linear, ll_linear.getWidth(), ll_linear.getHeight());
saveBitmap(bitmap1);
} else {
}
}
}
});
}
public void saveBitmap(Bitmap bitmap) {
File imagePath = new File("/sdcard/screenshotdemo.jpg");
FileOutputStream fos;
try {
fos = new FileOutputStream(imagePath);
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
fos.flush();
fos.close();
Toast.makeText(getApplicationContext(), imagePath.getAbsolutePath() + "", Toast.LENGTH_SHORT).show();
boolean_save = true;
btn_screenshot.setText("Check image");
Log.e("ImageSave", "Saveimage");
} catch (IOException e) {
Log.e("GREC", e.getMessage(), e);
}
}
public static Bitmap loadBitmapFromView(View v, int width, int height) {
Bitmap b = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;
}
private void fn_permission() {
if ((ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.READ_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED) ||
(ContextCompat.checkSelfPermission(getApplicationContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) != PackageManager.PERMISSION_GRANTED)) {
if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE))) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
if ((!ActivityCompat.shouldShowRequestPermissionRationale(MainActivity.this, Manifest.permission.WRITE_EXTERNAL_STORAGE))) {
ActivityCompat.requestPermissions(MainActivity.this, new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE},
REQUEST_PERMISSIONS);
}
} else {
boolean_permission = true;
}
}
@Override
public void onRequestPermissionsResult(int requestCode, String[] permissions, int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == REQUEST_PERMISSIONS) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
boolean_permission = true;
} else {
Toast.makeText(getApplicationContext(), "Please allow the permission", Toast.LENGTH_LONG).show();
}
}
}
}
谢谢我已经测试了很多代码,每次点击
NullPointerExeption
。我发现当我们的视图没有父视图时,提供的宽度和高度(Xml或Java)会被忽略,并被设置为MATCH\u parent
最后我提出了这个解决方案:
/**
* Take screen shot of the View
*
* @param v the view
* @param width_dp
* @param height_dp
*
* @return screenshot of the view as bitmap
*/
public static Bitmap takeScreenShotOfView(View v, int width_dp, int height_dp) {
v.setDrawingCacheEnabled(true);
// this is the important code :)
v.measure(View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), width_dp), View.MeasureSpec.EXACTLY),
View.MeasureSpec.makeMeasureSpec(dpToPx(v.getContext(), height_dp), View.MeasureSpec.EXACTLY));
v.layout(0, 0, v.getMeasuredWidth(), v.getMeasuredHeight());
v.buildDrawingCache(true);
// creates immutable clone
Bitmap b = Bitmap.createBitmap(v.getDrawingCache());
v.setDrawingCacheEnabled(false); // clear drawing cache
return b;
}
public static int dpToPx(Context context, int dp) {
Resources r = context.getResources();
return Math.round(TypedValue.applyDimension(TypedValue.COMPLEX_UNIT_DIP, dp, r.getDisplayMetrics()));
}
拍摄视图的屏幕截图,在参数中传递视图
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;
}
在这篇文章中,我找到了一些解决方案:我在这里尝试了被接受的答案,但是生成的输出有一些问题。这里的答案是对我有效的:实际上我没有找到合适的解决方案。不幸的是,图形缓存无法获取整个视图。这是一个非常复杂的解决方案。设备不会渲染屏幕外的任何内容(因为它不必渲染),因此在请求之前不会渲染视图。这里的问题是,平均布局没有实际的高度/宽度值,通常设置为匹配父/填充父。在我的例子中,我需要调查一个真实大小可访问的父级。Leon,你可以随时调用view.getWidth()和view.getHeight来获取飞行视图的尺寸。这段代码对我来说很好,但我想在一秒钟内连续拍摄24-25个屏幕截图,我可以每秒截图14-15张,但不能截图24-25张。“你能告诉我该怎么做吗?”法拉克耶维德,我和你有同样的问题,你有更好的解决办法吗?谢谢,很好,但是背景是黑色的。如何设置背景色?谢谢!有一段时间我很困惑,因为我想“但是我需要在设备中运行的部分是什么?”-没想到它会像那样工作。检查此答案以获得可能的解决方案。此库使用与上面相同的过程,但使用的形式更一般。(这不是一种优化的技术,但肯定是一种可用的技术)这种方法不太安全,图形缓存有一个限制,当您的视图很大(如滚动视图)时,getDrawingCache将返回null。在Android SDK中查找View.java和method buildDrawingCacheImpl,日志中也有警告“由于太大,无法放入软件层(或绘图缓存),需要…”它可以工作,但背景为黑色。我怎么能改变它?我知道了。需要更改第一个子元素的背景色。屏幕包含谷歌地图。它成功了,但是谷歌地图在截图中显示为黑色。
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;
}
fun View.getScreenShot():Bitmap{
return Bitmap.createBitmap(width,height,Bitmap.Config.ARGB_8888).apply {
draw(Canvas(this))
}
}