package com.sxwdsoft.recyclerviewapplication; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Paint; import android.graphics.Point; import android.graphics.PorterDuff; import android.graphics.PorterDuffXfermode; import android.graphics.Rect; import android.graphics.RectF; import android.os.Bundle; import android.support.v7.app.AppCompatActivity; import android.util.AttributeSet; import android.util.Log; import android.view.MotionEvent; import android.view.SurfaceHolder; import android.view.SurfaceView; import android.view.View; import android.view.ViewGroup; import android.view.Window; import android.widget.Button; import android.widget.RelativeLayout; import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; public class SurfaceActivity extends AppCompatActivity { private Bitmap bitmap; private SurfaceHolder holder; private boolean running = true; public static final int zoom = 1000; public static final int move = 1001; public int state = 0; private Rect srcRect, zoomRect; private int surfaceWidth, surfaceHeight; private int visibleScreenWidth, visibleScreenHieght; private MySurfaceView surfaceView; private int clipR = 200; private int[] clipXY; private int leftMax, rightMin, topMax, bottomMin; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); bitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.b); running = true; surfaceView = new MySurfaceView(this); ViewGroup.LayoutParams surfaceParams = new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT); RelativeLayout layout = new RelativeLayout(this); layout.setLayoutParams(new ViewGroup.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT)); RelativeLayout.LayoutParams params = new RelativeLayout.LayoutParams(RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT); params.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM); params.addRule(RelativeLayout.CENTER_IN_PARENT); Button button = new Button(this); button.setText("截屏"); layout.addView(surfaceView, surfaceParams); layout.addView(button, params); //截屏事件监听 button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { //停止缩放移动 running = false; //获取锁定画布 Canvas c = holder.lockCanvas(); //获取画布尺寸 int w = c.getWidth(); int h = c.getHeight(); //解锁画布 holder.unlockCanvasAndPost(c); //创建一个和画布一样大小尺寸的无内容的bitmap对象 Bitmap bit = Bitmap.createBitmap(w, h, Bitmap.Config.ARGB_8888); //绘制裁剪框 Rect src = new Rect(w / 2 - clipR, h / 2 - clipR, w / 2 + clipR, h / 2 + clipR); Rect dst = new Rect(0, 0, clipR * 2, clipR * 2); RectF rectF = new RectF(dst); rectF.left = src.left; rectF.right = src.right; rectF.top = src.top; rectF.bottom = src.bottom; Canvas canvas = new Canvas(bit); canvas.drawColor(Color.TRANSPARENT); Paint p = new Paint(); p.setAntiAlias(true); canvas.drawRoundRect(rectF, clipR, clipR, p); p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_IN)); //把画布上的冬衣全部绘制到bitmap上 canvas.drawBitmap(bitmap, srcRect, zoomRect, p); //裁剪图片 bit = Bitmap.createBitmap(bit, (int) rectF.left, (int) rectF.top, 2 * clipR, 2 * clipR); //保存图片 File file = new File(getExternalCacheDir() + File.separator + "a.png"); if (file.exists()) file.mkdir(); FileOutputStream out = null; try { out = new FileOutputStream(file); } catch (FileNotFoundException e) { e.printStackTrace(); } bit.compress(Bitmap.CompressFormat.PNG, 100, out); if (out != null) try { out.close(); } catch (IOException e) { e.printStackTrace(); } } }); setContentView(layout); Rect r = new Rect(); getWindow().getDecorView().getWindowVisibleDisplayFrame(r); visibleScreenWidth = r.width(); visibleScreenHieght = r.height() - r.top; } @Override public void onWindowFocusChanged(boolean hasFocus) { super.onWindowFocusChanged(hasFocus); View v = getWindow().findViewById(Window.ID_ANDROID_CONTENT); visibleScreenHieght = visibleScreenHieght - v.getTop(); } public class MySurfaceView extends SurfaceView implements SurfaceHolder.Callback, Runnable, View.OnTouchListener { private float bitmapScale; private int bitmapWidth, bitmapHeight; public MySurfaceView(Context context) { super(context); init(); } public MySurfaceView(Context context, AttributeSet attrs) { super(context, attrs); init(); } public MySurfaceView(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); init(); } //初始化 private void init() { holder = this.getHolder(); holder.addCallback(this); this.setOnTouchListener(this); bitmapScale = ((float) bitmap.getWidth()) / bitmap.getHeight(); } @Override protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { //测量view的大小 surfaceWidth = getDefaultSize(visibleScreenWidth, widthMeasureSpec); surfaceHeight = getDefaultSize(visibleScreenHieght, heightMeasureSpec); //没有调用父类的onMeasure则这个方法必须调用 setMeasuredDimension(surfaceWidth, surfaceHeight); } @Override public void surfaceCreated(SurfaceHolder holder) { running = true; //设置图片移动和缩放的最大与最小坐标 leftMax = surfaceWidth / 2 - clipR; rightMin = surfaceWidth / 2 + clipR; topMax = surfaceHeight / 2 - clipR; bottomMin = surfaceHeight / 2 + clipR; //获取图片的大小 bitmapWidth = bitmap.getWidth(); bitmapHeight = bitmap.getHeight(); //缩放bitmap尺寸 if (bitmapWidth > surfaceWidth || bitmapHeight > surfaceHeight) { bitmapWidth = surfaceWidth; bitmapHeight = (int) (surfaceWidth / bitmapScale); if (bitmapHeight > surfaceHeight) { bitmapHeight = surfaceHeight; bitmapWidth = (int) (surfaceHeight * bitmapScale); } } int x0 = (surfaceWidth - bitmapWidth) / 2; int y0 = (surfaceHeight - bitmapHeight) / 2; int x1 = (surfaceWidth + bitmapWidth) / 2; int y1 = (surfaceHeight + bitmapHeight) / 2; //图片显示的区域 zoomRect = new Rect(x0, y0, x1, y1); //要显示图片 srcRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight()); bitW = bitmapWidth; bitH = bitmapHeight; clipXY = new int[]{surfaceWidth / 2, surfaceHeight / 2}; new Thread(this).start(); } @Override public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) { } @Override public void surfaceDestroyed(SurfaceHolder holder) { running = false; } private Point point = new Point();//点击点 private boolean canDrag = false;//判断是否点击在图片上,否则拖动无效 private int offsetX = 0, offsetY = 0;//点击点离图片左上角的距离 private float initDistance; private int dy; private int bitW, bitH; @Override public boolean onTouch(View v, MotionEvent event) { Log.i("asd", "action=" + event.getAction()); switch (event.getAction()) { //手按下的时候 case MotionEvent.ACTION_DOWN: state = move; point.x = (int) event.getX(); point.y = (int) event.getY(); if (zoomRect.contains(point.x, point.y)) { canDrag = true; offsetX = point.x - zoomRect.left; offsetY = point.y - zoomRect.top; } break; //移动的时候 case MotionEvent.ACTION_MOVE: if (!canDrag) break; if (state == move) { zoomRect.left = (int) event.getX() - offsetX; zoomRect.top = (int) event.getY() - offsetY; zoomRect.right = zoomRect.left + bitW; zoomRect.bottom = zoomRect.top + bitH; if (zoomRect.left > leftMax) { zoomRect.left = leftMax; zoomRect.right = zoomRect.left + bitW; } if (zoomRect.right < rightMin) { zoomRect.right = rightMin; zoomRect.left = zoomRect.right - bitW; } if (zoomRect.top > topMax) { zoomRect.top = topMax; zoomRect.bottom = zoomRect.top + bitH; } if (zoomRect.bottom < bottomMin) { zoomRect.bottom = bottomMin; zoomRect.top = zoomRect.bottom - bitH; } } else if (state == zoom) { float move = getDistance(event); int dx0 = (int) (move - initDistance); zoomRect.left -= dx0; zoomRect.right += dx0; if (zoomRect.left > leftMax || zoomRect.right < rightMin) { zoomRect.left += dx0; zoomRect.right -= dx0; return true; } bitW = zoomRect.right - zoomRect.left; bitH = (int) (bitW / bitmapScale); int dy0 = (bitH - bitmapHeight) / 2; int d1 = dy0 - dy; zoomRect.top -= d1; zoomRect.bottom += d1; if (zoomRect.top > topMax || zoomRect.bottom < bottomMin) { zoomRect.top += d1; zoomRect.bottom -= d1; zoomRect.left += dx0; zoomRect.right -= dx0; bitW = zoomRect.right - zoomRect.left; bitH = (int) (bitW / bitmapScale); } else { initDistance = move; dy = dy0; } } break; case 261: state = zoom; initDistance = getDistance(event); break; case MotionEvent.ACTION_POINTER_UP: state = -1; canDrag = false; break; case MotionEvent.ACTION_UP: state = -1; canDrag = false; break; default: state = -1; canDrag = false; break; } return true; } @Override public void run() { //绘制裁剪框bitmap图片 Paint paint = new Paint(); //给画笔设置颜色 paint.setAlpha(Color.TRANSPARENT); //设置画笔样式 paint.setStyle(Paint.Style.FILL); //消除锯齿 paint.setAntiAlias(true); //设置绘制图层的显示 paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN)); //创建一个有尺寸的空的bitmap Bitmap bit = Bitmap.createBitmap(surfaceWidth, surfaceHeight, Bitmap.Config.ARGB_8888); // Canvas tempcCanvas = new Canvas(bit); tempcCanvas.drawColor(Color.parseColor("#55000000")); tempcCanvas.drawCircle(clipXY[0], clipXY[1], clipR, paint); while (running) { Canvas canvas = holder.lockCanvas();//获取画布 if (canvas == null) continue; //给你画布绘制颜色 canvas.drawColor(Color.WHITE); //把图片绘制到画布上 srcRect:图片显示的大小,zoomRect:图片显示的区域 canvas.drawBitmap(bitmap, srcRect, zoomRect, null); //裁剪框绘制到画布上 canvas.drawBitmap(bit, 0, 0, null); holder.unlockCanvasAndPost(canvas);// 解锁画布,提交画好的图像 } } } //获取起始位置的距离 private float getDistance(MotionEvent event) { float dx = event.getX(0) - event.getX(1); float dy = event.getY(0) - event.getY(1); return (float) Math.sqrt(dx * dx + dy * dy); } }