android自定义view图片绘制

1、PaintViewActivity
import android.app.Activity;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.view.View;

import com.HBuilder.integrate.PaintIt.PaintView;

import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;

public class PaintViewActivity extends Activity implements View.OnClickListener,View.OnLongClickListener {


    private  Bitmap bitmap;
    private PaintView paintView;



    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_paint_view);
        paintView = findViewById(R.id.paintView);
        final String iPath = this.getIntent().getStringExtra("url");
        //为了下载图片资源,开辟一个新的子线程
        Thread t=new Thread(){
            public void run() {
                //下载图片的路径
                try {
                    //对资源链接
                    URL url=new URL(iPath);
                    //打开输入流
                    InputStream inputStream=url.openStream();
                    //对网上资源进行下载转换位图图片
                    bitmap=BitmapFactory.decodeStream(inputStream);
                    paintView.initBitmap(bitmap);
                } catch (MalformedURLException e) {
                    e.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            };
        };
        t.start();

        findViewById(R.id.paint).setOnClickListener(this);
        findViewById(R.id.text).setOnClickListener(this);
        findViewById(R.id.back).setOnClickListener(this);
        findViewById(R.id.clear).setOnClickListener(this);
        findViewById(R.id.save).setOnClickListener(this);
        findViewById(R.id.move).setOnClickListener(this);
        findViewById(R.id.zoom).setOnClickListener(this);
        findViewById(R.id.reset).setOnClickListener(this);
    }



    @Override
    public void onClick(View v) {
        switch (v.getId()) {

            case R.id.paint:
                // use paint
                paintView.paint();
                break;
            case R.id.text:
                // use paint
                paintView.text();
                break;
            case R.id.back:
                // use paint
                paintView.back();
                break;
            case R.id.clear:
                // use paint
                paintView.Clear();
                break;
            case R.id.save:
                // use paint
                paintView.save();
                break;
            case R.id.move:
                // use paint
                paintView.move();
                break;
            case R.id.zoom:
                // use paint
                paintView.zoom();
                break;
            case R.id.reset:
                // use paint
                paintView.reset();
                break;

        }
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        super.onActivityResult(requestCode, resultCode, data);

    }

    @Override
    public boolean onLongClick(View v) {
       return true;
    }


    @Override
    public void onBackPressed() {
        paintView.showCustomToast("返回");
        finish();
        //TODO something
        super.onBackPressed();

    }


}

2、PaintView

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.Rect;
import android.os.Environment;
import android.util.AttributeSet;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.EditText;
import android.widget.TextView;
import android.widget.Toast;

import com.HBuilder.integrate.R;
import com.HBuilder.integrate.TextNode;

import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.List;


/**
 * Package com.hc.studyview
 * Created by HuaChao on 2016/6/3.
 */
public class PaintView extends View {

	private Context context;
	private boolean isPaint = false;//空心正方形
	private boolean isText = false;//文字
	private boolean isMove = true;//移动
	private boolean isZoom = false;//缩放
	private Paint mPaint;//画笔
	private Bitmap originalBitmap;//原始图片
	private Bitmap bitmap;//处理后图片
	private List originalGraphical; //原始图形
	private float rX, rY;//矩形起点
	private float x1,y1,x2,y2;//手指移动矩形坐标
	private float x3,y3;//图形移动起始坐标
	private int currentLeft,currentTop;//当前图形偏移量
	private Rect mSrcRect, mDestRect;//图片绘画区域
	private double nLenStart;//缩放起始长度
	private double zoom=1;//缩放比例
	private int fontSize = 50;

	public PaintView(Context context) {
		super(context);
		this.context = context;
		this.originalGraphical = new ArrayList<>();
		this.mPaint = new Paint();
	}


	public PaintView(Context context, AttributeSet attrs) {
		super(context, attrs);
		this.context = context;
		this.originalGraphical = new ArrayList<>();
		this.mPaint = new Paint();
	}
	//切换至矩形绘图
	public void paint(){
		showCustomToast("矩形");
		isPaint = true;
		isText = false;
		isMove = false;
		isZoom = false;
	}
	//矩形坐标填充
	private void rectPoint(float x,float y){
		x1 = rX>x?x:rX;
		y1 = rY>y?y:rY;
		x2 = rX0){
			originalGraphical.remove(originalGraphical.size()-1);
			invalidate();
		}
	}
	//清空
	public void Clear(){
		showCustomToast("清空");
		isPaint = false;
		isText = false;
		isMove = false;
		isZoom = false;
		originalGraphical.clear();
		invalidate();
	}
	//切换至移动图片
	public void move(){
		showCustomToast("移动");
		isPaint = false;
		isText = false;
		isMove = true;
		isZoom = false;
	}
	//图形移动偏移量计算
	private void img_move(float x,float y){
		int moveLeft = x>x3?15:-15;
		int moveTop = y>y3?15:-15;
		currentLeft = currentLeft + moveLeft;
		currentTop = currentTop + moveTop;
		x3 = x;
		y3 = y;
	}
	//缩放
	public void zoom(){
		showCustomToast("缩放");
		isPaint = false;
		isText = false;
		isMove = false;
		isZoom = true;
	}
	public void reset(){
		showCustomToast("复原");
		isPaint = false;
		isText = false;
		isMove = false;
		isZoom = false;
		zoom =1;
		invalidate();
	}
	//缩放比例计算
	private void zoomComputer(MotionEvent event){
		if ((event.getAction() & MotionEvent.ACTION_MASK) == MotionEvent.ACTION_POINTER_DOWN ){
			int xlen = Math.abs((int) event.getX(0) - (int) event.getX(1));
			int ylen = Math.abs((int) event.getY(0) - (int) event.getY(1));
			nLenStart = Math.sqrt((double) xlen * xlen + (double) ylen * ylen);
		} else {
			int xlen = Math.abs((int) event.getX(0) - (int) event.getX(1));
			int ylen = Math.abs((int) event.getY(0) - (int) event.getY(1));
			double nLenEnd = Math.sqrt((double) xlen * xlen + (double) ylen * ylen);
			double f = nLenEnd / nLenStart;
			if (f != 1) {
				zoom += (f > 1 ? +0.02 : -0.02);
			}
			if (zoom > 2) {
				zoom = 2;
			}
			if (zoom < 0.5) {
				zoom = 0.5;
			}
		}
	}


	//图片绘画计算
	public void bitmapTranslate() {
		Matrix matrix = new Matrix();
		matrix.setScale((float)zoom,(float)zoom);
		bitmap = Bitmap.createBitmap(originalBitmap, 0, 0, originalBitmap.getWidth(), originalBitmap.getHeight(), matrix, true);
		mSrcRect.right = bitmap.getWidth();
		mSrcRect.bottom = bitmap.getHeight();
		mDestRect.left = currentLeft;
		mDestRect.right = currentLeft + bitmap.getWidth();
		mDestRect.top = currentTop;
		mDestRect.bottom = currentTop + bitmap.getHeight();
	}

	//矩形绘画计算
	private Rect rectTranslate(Rect rect){
		return new Rect((int)(rect.left*zoom+currentLeft),(int)(rect.top*zoom+currentTop),(int)(rect.right*zoom+currentLeft),(int)(rect.bottom*zoom+currentTop));
	}
	//文字绘画机选
	private TextNode textTranslate(TextNode textNode){
		return new TextNode(textNode.getText(),(float) (textNode.getLeft()*zoom+currentLeft),(float)( textNode.getTop()*zoom+currentTop));
	}



	@Override
		protected void onDraw(Canvas canvas) {
		super.onDraw(canvas);
		if(bitmap!=null){
			bitmapTranslate();
			canvas.drawBitmap(bitmap,mSrcRect, mDestRect,mPaint );
		}
		for(Object o : originalGraphical) {
			if (o instanceof Rect) {
				mPaint.setStyle(Paint.Style.STROKE);
				canvas.drawRect(rectTranslate((Rect)o) , mPaint);
			} else if (o instanceof TextNode) {
				mPaint.setStyle(Paint.Style.FILL);
				mPaint.setTextSize((int)(fontSize*zoom));
				TextNode t = textTranslate((TextNode)o);
				canvas.drawText(t.getText(),t.getLeft(), t.getTop(), mPaint);
			}
		}
		//手指移动绘制矩形
		if(isPaint) {
			mPaint.setStyle(Paint.Style.STROKE);
			canvas.drawRect(x1, y1, x2, y2, mPaint);
		}
			//canvas.drawPath(mPath, mEraserPaint);
	}


	// 初始化画笔
	private void Init_Paint(int color ,int width){
		mPaint.setAntiAlias(true);
		mPaint.setDither(true);
		mPaint.setColor(color);
		mPaint.setStyle(Paint.Style.STROKE);
		mPaint.setStrokeJoin(Paint.Join.ROUND);
		mPaint.setStrokeCap(Paint.Cap.ROUND);
		mPaint.setStrokeWidth(width);
	}
	//提示框
	public void showCustomToast(String toast) {
		LayoutInflater inflater = LayoutInflater.from(context);
		View view = inflater.inflate(R.layout.toast_item, (ViewGroup)findViewById(R.id.toast_item));
		TextView text = (TextView) view.findViewById(R.id.toast_text);
		text.setText(toast);
		Toast tempToast = new Toast(context);
		tempToast.setGravity(Gravity.CENTER_HORIZONTAL | Gravity.CENTER, 0, 0);
		tempToast.setDuration(Toast.LENGTH_SHORT);
		tempToast.setView(view);
		tempToast.show();
	}



	@Override
	public boolean onTouchEvent(MotionEvent event) {


			int nCnt = event.getPointerCount();
			if(nCnt==2){
				isMove = false;
				isPaint = false;
				isText = false;
				zoomComputer(event);
				isMove = true;
				invalidate();
				return true;
			}

			float x = event.getX();
			float y = event.getY();
			switch (event.getAction()) {
				case MotionEvent.ACTION_DOWN:
					touch_down(x, y);
					break;

				case MotionEvent.ACTION_MOVE:
					touch_move(x,y);
					invalidate();
					break;

				case MotionEvent.ACTION_UP:
					touch_up(x,y);
					invalidate();
					break;
			}
			return true;
	}
	//手指按下
	private void touch_down(float x, float y) {
		if(isPaint){
			this.rX = x;
			this.rY = y;
		}
	}
	//手指移动
	private void touch_move(float x, float y) {
		if(isPaint){
			rectPoint(x,y);
		}else if(isMove){
			img_move(x,y);
		}

	}
	//手指弹起
	private void touch_up(final float x,final float y){
		if(isPaint){
			rectPoint(x,y);
			Rect r = new Rect((int)(x1/zoom-currentLeft/zoom),(int)(y1/zoom-currentTop/zoom),(int)(x2/zoom-currentLeft/zoom),(int)(y2/zoom-currentTop/zoom));
			originalGraphical.add(r);
		}else if(isText){
			edit(x,y);
		}

	}
	//初始化图片
	public void initBitmap(Bitmap bitmap) {
		Init_Paint(UserInfo.PaintColor, UserInfo.PaintWidth);
		this.bitmap = bitmap;
		this.originalBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), new Matrix(), true);
		mSrcRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		mDestRect = new Rect(0, 0, bitmap.getWidth(), bitmap.getHeight());
		invalidate();
	}
	//保存图片
	public void save() {
		Bitmap copyBitmap = Bitmap.createBitmap(originalBitmap.getWidth(), originalBitmap.getHeight(), Bitmap.Config.ARGB_8888);
		Canvas c = new Canvas(copyBitmap);
		c.drawBitmap(originalBitmap,new Matrix(),mPaint);
		for(Object o : originalGraphical) {
			if (o instanceof Rect) {
				mPaint.setStyle(Paint.Style.STROKE);
				c.drawRect((Rect) o, mPaint);
			} else if (o instanceof TextNode) {
				mPaint.setStyle(Paint.Style.FILL);
				mPaint.setTextSize(fontSize);
				TextNode t = (TextNode)o;
				c.drawText(t.getText(),t.getLeft(),t.getTop(), mPaint);
			}
		}

		FileOutputStream fos;
		String imagePath = "";
		try {
			// 判断手机设备是否有SD卡
			boolean isHasSDCard = Environment.getExternalStorageState().equals(
					android.os.Environment.MEDIA_MOUNTED);
			if (isHasSDCard) {
				// SD卡根目录
				File sdRoot = Environment.getExternalStorageDirectory();
				File file = new File(sdRoot, Calendar.getInstance().getTimeInMillis()+".png");
				fos = new FileOutputStream(file);
				imagePath = file.getAbsolutePath();
				showCustomToast(file.getPath());
			} else
				throw new Exception("创建文件失败!");

			copyBitmap.compress(Bitmap.CompressFormat.PNG, 90, fos);

			fos.flush();
			fos.close();

		} catch (Exception e) {
			e.printStackTrace();
		}

		this.destroyDrawingCache();
	}






} 
  

3、TextNode

import android.app.Application;

import java.util.ArrayList;

/**
 * Created by liufengkai on 15/8/25.
 */
public class PathNode extends Application {
    public class Node {
        public Node() {
        }

        public float x;
        public float y;
        public int PenColor;
        public int TouchEvent;
        public int PenWidth;
        public boolean IsPaint;
        public long time;
        public int EraserWidth;

    }

    private ArrayList PathList;


    public ArrayList getPathList() {
        return PathList;
    }

    public void addNode(Node node) {
        PathList.add(node);
    }

    public Node NewAnode() {
        return new Node();
    }


    public void clearList() {
        PathList.clear();
    }

    @Override
    public void onCreate() {
        super.onCreate();
        PathList = new ArrayList();
    }

    public void setPathList(ArrayList pathList) {
        PathList = pathList;
    }

    public Node getTheLastNote() {
        return PathList.get(PathList.size() - 1);
    }

    public void deleteTheLastNote() {
        PathList.remove(PathList.size() - 1);
    }

    public PathNode() {
        PathList = new ArrayList<>();
    }

}

4、layout布局文件



    




    
        
    

    
        


 
  

                            
                        
                    
                    
                    

你可能感兴趣的:(android学习笔记)