Android Studio 基础 之 截图,指定截图区域动态截图
目录
Android Studio 基础 之 截图,指定截图区域动态截图
下面是简单的只要 x, y, width,heigth 输入进行屏幕截图的代码(也是从上面代码截取出来的,方便后期封装为工具类)
一、简单介绍
Android 开发中的一些基础操作,使用整理,便于后期使用。
本节介绍,在Android中,实现动态截图,指定区域进行图片截取的功能。
二、实现原理
1、使用 Touch 和View 实现指定区域绘制
2、使用 bitmap = Bitmap.createBitmap(bitmap, x, y, width, height) 得到指定区域的图像
三、注意事项
1、这里指在图片区域添加了 Touch 监听事件,所以 Touch 开始点要点在图片上
四、预览效果
五、实现步骤
1、打开 Android Studio,新建一个工程(或者模块)
2、构建一个 Phone & Table Module
3、取一个名字
4、建立一个 Empty Activiy
5、取一个名字
6、在工程中添加一个图片,作为截图的基础
7、layout 布局如图
8、两个脚本,一个十 View 实现区域绘制设置,MainActivity 实现 Touch 和图片截取、保存
9、打包运行的效果
六、关键代码
1、MainActivity.java
package com.pf.screenshot;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import android.app.ActionBar;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Rect;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.Button;
import android.widget.ImageView;
public class MainActivity extends AppCompatActivity implements OnTouchListener{
private static final String TAG = "Screenshot";
private int x;//绘画开始的横坐标
private int y;//绘画开始的纵坐标
private int m;//绘画结束的横坐标
private int n;//绘画结束的纵坐标
private int width;//绘画的宽度
private int height;//绘画的高度
private Bitmap bitmap;//生成的位图
private MyView myView;//绘画选择区域
private ImageView image1;
private ImageView image2;
private Button button;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
// 初始化,获取 UI 元素
image1 = (ImageView) findViewById(R.id.image1);
image2 = (ImageView) findViewById(R.id.image2);
myView = new MyView(this);
button = (Button) findViewById(R.id.btnscreen);
// 监听按钮事件
button.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if(myView.isSign()){
myView.setSeat(0, 0, 0, 0);
myView.setSign(false);
button.setText("停止截屏");
}else{
myView.setSign(true);
button.setText("开始截屏");
image2.setImageBitmap(null);
}
myView.postInvalidate();
}
});
// 在图片上监听触摸事件
image1.setOnTouchListener(this);
// 添加 view
this.addContentView(myView, new ActionBar.LayoutParams(ActionBar.LayoutParams.WRAP_CONTENT, ActionBar.LayoutParams.WRAP_CONTENT));
}
/**
* 获取选择框在屏幕的位置
* @param v
* @param event
* @return
*/
@Override
public boolean onTouch(View v, MotionEvent event) {
// 记录初始位置
if(event.getAction() == MotionEvent.ACTION_DOWN){
x = 0;
y = 0;
width = 0;
height = 0;
x = (int) event.getX();
y = (int) event.getY();
Log.i(TAG, "onTouch: x = "+x +" y = "+y);
}
// 移动的时候进行绘制框
if(event.getAction() == MotionEvent.ACTION_MOVE){
m = (int) event.getX();
n = (int) event.getY();
myView.setSeat(x, y, m, n);
myView.postInvalidate();
Log.i(TAG, "onTouch: x = "+x +" y = "+y +" m = "+m +" n = "+n);
}
// 抬起的时候整理绘制的框 长宽
if(event.getAction() == MotionEvent.ACTION_UP){
if(event.getX()>x){
width = (int)event.getX()-x;
}else{
width = (int)(x-event.getX());
x = (int) event.getX();
}
if(event.getY()>y){
height = (int) event.getY()-y;
}else{
height = (int)(y-event.getY());
y = (int) event.getY();
}
Log.i(TAG, "onTouch: x = "+x +" y = "+y +" m = "+m +" n = "+n);
// 设置图片显示
image2.setImageBitmap(getBitmap(this));
}
if(myView.isSign()){
return false;
}else{
return true;
}
}
/**
* 根据绘制的区域生成图片
* @param activity
* @return
*/
private Bitmap getBitmap(Activity activity){
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
bitmap = view.getDrawingCache();
Rect frame = new Rect();
activity.getWindow().getDecorView().getWindowVisibleDisplayFrame(frame);
int toHeight = frame.top;
//bitmap = Bitmap.createBitmap(bitmap, x, y+2*toHeight, width, height);
// 108是上边界的距离(大约上边框栏的大小 这里根据自己情况调整)
bitmap = Bitmap.createBitmap(bitmap, x, y+2*toHeight + 108, width, height);
//这个能获得上边界的画面
//bitmap = Bitmap.createBitmap(bitmap, x, y, width, height);
try {
// 保存截图的而位置(需要sdcard写入权限)
FileOutputStream fout = new FileOutputStream("mnt/sdcard/testScreenShot.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fout);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
view.setDrawingCacheEnabled(false);
return bitmap;
}
}
2、MyView.java
package com.pf.screenshot;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.view.View;
public class MyView extends View {
private int x;
private int y;
private int m;
private int n;
private boolean sign;//绘画标记位
private Paint paint;//画笔
public MyView(Context context) {
super(context);
paint = new Paint(Paint.FILTER_BITMAP_FLAG);
}
/**
* 设置画笔
* @param canvas
*/
@Override
protected void onDraw(Canvas canvas) {
if(sign){
paint.setColor(Color.TRANSPARENT);
}else{
paint.setColor(Color.GREEN);
paint.setAlpha(80);
canvas.drawRect(new Rect(x, y, m, n), paint);
}
super.onDraw(canvas);
}
public void setSeat(int x,int y,int m,int n){
this.x = x;
this.y = y;
this.m = m;
this.n = n;
}
public boolean isSign() {
return sign;
}
public void setSign(boolean sign) {
this.sign = sign;
}
}
3、AndroidMainfest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.pf.screenshot">
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE"/>
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
<application
android:allowBackup="true"
android:icon="@mipmap/ic_launcher"
android:label="@string/app_name"
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@style/AppTheme">
<activity android:name=".MainActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>
</application>
</manifest>
4、activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="fill_parent"
android:layout_height="fill_parent"
android:orientation="vertical" >
<ImageView
android:layout_width="fill_parent"
android:layout_height="300dip"
android:id="@+id/image1"
android:src="@drawable/image"
/>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginTop="20dip"
>
<ImageView
android:layout_width="100dp"
android:layout_height="100dp"
android:id="@+id/image2"
android:layout_alignParentLeft="true"
android:layout_marginLeft="10dip"
/>
<Button
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:id="@+id/btnscreen"
android:text="停止截屏"
android:layout_alignParentRight="true"
android:layout_marginRight="10dip"
/>
</RelativeLayout>
</LinearLayout>
7、附录简版截图
下面是简单的只要 x, y, width,heigth 输入进行屏幕截图的代码(也是从上面代码截取出来的,方便后期封装为工具类)
1、MainActivity.java
package com.pf.screenshot_xan;
import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Bitmap;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.util.Log;
import android.view.Display;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
public class MainActivity extends AppCompatActivity {
private static final String TAG = "MainActivity";
private Bitmap bitmap;//生成的位图
private ImageView img;
private Button btn;
int width;
int height;
// 判断授权列表
private List<String> unGrantedPermissions;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
// 获取 UI 元素
setContentView(R.layout.activity_main);
img = findViewById(R.id.img);
btn = findViewById(R.id.btn);
// 获取屏幕的宽高
Display display = getWindowManager().getDefaultDisplay();
width = display.getWidth();
height = display.getHeight();
Log.i(TAG, "width = " + width + ",height = " + height);
// 点击按钮截图
btn.setOnClickListener(new View.OnClickListener(){
@Override
public void onClick(View v) {
img.setImageBitmap(getBitmap(MainActivity.this, 0,0, width,height));
}
});
checkPermissions(MainActivity.this);
}
/**
* 获取屏幕截图
* @param activity
* @param x
* @param y
* @param width
* @param height
* @return
*/
private Bitmap getBitmap(Activity activity, int x, int y, int width, int height){
View view = activity.getWindow().getDecorView();
view.setDrawingCacheEnabled(true);
view.buildDrawingCache();
bitmap = view.getDrawingCache();
// 截图位置 生成的 bitmap
bitmap = Bitmap.createBitmap(bitmap, x, y, width, height);
try {
// 保存地址
FileOutputStream fout = new FileOutputStream("mnt/sdcard/test.png");
bitmap.compress(Bitmap.CompressFormat.PNG, 100, fout);
} catch (FileNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
view.setDrawingCacheEnabled(false);
return bitmap;
}
/**
* 申请权限
* @param activity
*/
public void checkPermissions(Activity activity) {
Log.i(TAG, "checkPermissions: 检测权限");
unGrantedPermissions = new ArrayList();
final String[] MANDATORY_PERMISSIONS = new String[]{ "android.permission.CAMERA",
"android.permission.READ_EXTERNAL_STORAGE","android.permission.WRITE_EXTERNAL_STORAGE"
};
Log.i(TAG, "checkPermissions: MANDATORY_PERMISSIONS :"+MANDATORY_PERMISSIONS.toString());
for (String permission : MANDATORY_PERMISSIONS) {
Log.i(TAG, "checkPermissions: unGrantedPermissions");
if (ContextCompat.checkSelfPermission(activity, permission) != PackageManager.PERMISSION_GRANTED) {
unGrantedPermissions.add(permission);
}
}
if (unGrantedPermissions.size() != 0) {//已经获得了所有权限,开始加入聊天室
String[] array = new String[unGrantedPermissions.size()];
ActivityCompat.requestPermissions(activity, unGrantedPermissions.toArray(array), 0);
Log.i(TAG, "checkPermissions: 已经获得了所有权限");
}
Log.i(TAG, "checkPermissions: Is Over");
}
}
2、activity_main.xml
<?xml version="1.0" encoding="utf-8"?>
<android.support.constraint.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">
<ImageView
android:id="@+id/img"
android:layout_width="match_parent"
android:layout_height="match_parent"
app:layout_constraintStart_toStartOf="parent"
app:layout_constraintTop_toTopOf="parent"
app:srcCompat="@mipmap/ic_launcher" />
<Button
android:id="@+id/btn"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="160dp"
android:layout_marginTop="60dp"
android:text="点击截图"
app:layout_constraintStart_toStartOf="parent"
/>
</android.support.constraint.ConstraintLayout>