package com.yjkj.sandihuabing.view.widget;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.PorterDuff;
import android.graphics.PorterDuffXfermode;
import android.net.Uri;
import android.os.Environment;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;
import com.yjkj.sandihuabing.model.Coord;
import com.yjkj.sandihuabing.util.Util;
import java.io.File;
import java.io.FileOutputStream;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
/**
* Created by yunjia on 2016/11/4.
*/
public class TuyaView extends View{
private Context context;
private Bitmap mBitmap;
private Canvas mCanvas;
private Path mPath;
private Paint mBitmapPaint;// 画布的画笔
private Paint mPaint;// 真实的画笔
private float mX, mY;// 临时点坐标
private static final float TOUCH_TOLERANCE = 4;
// 保存Path路径的集合
private static List<DrawPath> savePath;
// 保存已删除Path路径的集合
private static List<DrawPath> deletePath;
// 记录Path路径的坐标点
private List<Coord> coordList;
private List<List<Coord>> list;
private List<Coord> coords;
private DrawPath dp;
private int screenWidth, screenHeight;
private int currentColor = Color.BLACK;
private int currentSize = 10;
private class DrawPath {
public Path path;// 路径
public Paint paint;// 画笔
}
public TuyaView(Context context, int w, int h) {
super(context);
this.context = context;
screenWidth = w;
screenHeight = h;
setLayerType(LAYER_TYPE_SOFTWARE,null);//设置默认样式,去除dis-in的黑色方框以及clear模式的黑线效果
initCanvas();
savePath = new ArrayList<DrawPath>();
deletePath = new ArrayList<DrawPath>();
coordList = new ArrayList<>();
coords = new ArrayList<>();
list = new ArrayList<>();
}
public void initCanvas() {
setPaintStyle();
mBitmapPaint = new Paint(Paint.DITHER_FLAG);
//画布大小
mBitmap = Bitmap.createBitmap(screenWidth, screenHeight, Bitmap.Config.ARGB_8888);
mBitmap.eraseColor(Color.argb(0, 0, 0, 0));
mCanvas = new Canvas(mBitmap); //所有mCanvas画的东西都被保存在了mBitmap中
mCanvas.drawColor(Color.TRANSPARENT);
}
//初始化画笔样式
private void setPaintStyle() {
mPaint = new Paint();
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);// 设置外边缘
mPaint.setStrokeCap(Paint.Cap.ROUND);// 形状
mPaint.setAntiAlias(true);
mPaint.setDither(true);
}
@Override
public void onDraw(Canvas canvas) {
//canvas.drawColor(0xFFAAAAAA);
// 将前面已经画过得显示出来
canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
if (mPath != null) {
// 实时的显示
canvas.drawPath(mPath, mPaint);
}
}
private void touch_start(float x, float y) {
mPath.moveTo(x, y);
mX = x;
mY = y;
}
private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(mY - y);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
// 从x1,y1到x2,y2画一条贝塞尔曲线,更平滑(直接用mPath.lineTo也可以)
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
//mPath.lineTo(mX,mY);
mX = x;
mY = y;
if(mPaint.getColor() == Color.BLACK && mPaint.getStrokeWidth() == currentSize){
// coords.add(new Coord(Util.format(x/screenWidth),Util.format(y/screenHeight)));
coordList.add(new Coord(Util.format(x/screenWidth),Util.format(y/screenHeight)));
}
if(mPaint.getColor() == Color.TRANSPARENT && mPaint.getStrokeWidth() == 80){
coords.add(new Coord(Util.format(x/screenWidth),Util.format(y/screenHeight)));
}
}
}
private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);
//将一条完整的路径保存下来
savePath.add(dp);
mPath = null;// 重新置空
if(coordList.size() > 0){
list.add(coordList);
coordList = new ArrayList<>();
}
// if(coords.size() > 0 && list.size() > 0){
// for(int i = 0;i < list.size();i++){
// List<Coord> list1 = list.get(i);
// for(int j= 0; j < list1.size();j++){
// for(int q = 0;q < coords.size();q++){
// if(list1.contains(coords.get(q))){
// list1.remove(j);
// q--;
// }
// }
//
//
// }
// }
// coords = new ArrayList<>();
// }
}
/**
* 画图
*/
public void brush(){
setPaintStyle();
mPaint.setColor(currentColor);
mPaint.setStrokeWidth(currentSize);
}
/**
* 橡皮
*/
public void eraser(){
setPaintStyle();
mPaint.setAlpha(0);
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
mPaint.setColor(Color.TRANSPARENT);
mPaint.setStrokeWidth(80);
}
/**
* 撤销
* 撤销的核心思想就是将画布清空,
* 将保存下来的Path路径最后一个移除掉,
* 重新将路径画在画布上面。
*/
public void undo() {
if (savePath != null && savePath.size() > 0) {
DrawPath drawPath = savePath.get(savePath.size() - 1);
deletePath.add(drawPath);
savePath.remove(savePath.size() - 1);
redrawOnBitmap();
}
}
/**
* 重做
*/
public void redo() {
if (savePath != null && savePath.size() > 0) {
savePath.clear();
redrawOnBitmap();
}
list.clear();
coords.clear();
coordList.clear();
}
private void redrawOnBitmap() {
/*mBitmap = Bitmap.createBitmap(screenWidth, screenHeight,
Bitmap.Config.RGB_565);
mCanvas.setBitmap(mBitmap);// 重新设置画布,相当于清空画布*/
initCanvas();
Iterator<DrawPath> iter = savePath.iterator();
while (iter.hasNext()) {
DrawPath drawPath = iter.next();
mCanvas.drawPath(drawPath.path, drawPath.paint);
}
invalidate();// 刷新
}
/**
* 恢复,恢复的核心就是将删除的那条路径重新添加到savapath中重新绘画即可
*/
public void recover() {
if (deletePath.size() > 0) {
//将删除的路径列表中的最后一个,也就是最顶端路径取出(栈),并加入路径保存列表中
DrawPath dp = deletePath.get(deletePath.size() - 1);
savePath.add(dp);
//将取出的路径重绘在画布上
mCanvas.drawPath(dp.path, dp.paint);
//将该路径从删除的路径列表中去除
deletePath.remove(deletePath.size() - 1);
invalidate();
}
}
@Override
public boolean onTouchEvent(MotionEvent event) {
float x = event.getX();
float y = event.getY();
switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
// 每次down下去重新new一个Path
mPath = new Path();
//每一次记录的路径对象是不一样的
dp = new DrawPath();
dp.path = mPath;
dp.paint = mPaint;
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
//保存到sd卡
public void saveToSDCard() {
//获得系统当前时间,并以该时间作为文件名
SimpleDateFormat formatter = new SimpleDateFormat("yyyyMMddHHmmss");
Date curDate = new Date(System.currentTimeMillis());//获取当前时间
String str = formatter.format(curDate) + "paint.png";
File file = new File("sdcard/" + str);
FileOutputStream fos = null;
try {
fos = new FileOutputStream(file);
} catch (Exception e) {
e.printStackTrace();
}
mBitmap.compress(Bitmap.CompressFormat.PNG, 100, fos);
//发送Sd卡的就绪广播,要不然在手机图库中不存在
Intent intent = new Intent(Intent.ACTION_MEDIA_MOUNTED);
intent.setData(Uri.fromFile(Environment.getExternalStorageDirectory()));
context.sendBroadcast(intent);
Log.e("TAG", "图片已保存");
}
//选择画笔大小
public void selectPaintSize(int which) {
//int size = Integer.parseInt(this.getResources().getStringArray(R.array.paintsize)[which]);
currentSize = which;
setPaintStyle();
}
public Bitmap getmBitmap(){
return mBitmap;
}
public List<DrawPath> getSavePath(){
return savePath;
}
public List<Coord> getCoordList(){
return coordList;
}
public List<List<Coord>> getList(){
return list;
}
}