Android图形图像处理:添加涂鸦文字

时间:2019-02-21
本文章向大家介绍Android图形图像处理:添加涂鸦文字,主要包括Android图形图像处理:添加涂鸦文字使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

先看运行效果:

 

关键的PaintView:

package com.zhangphil;

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;

import java.util.ArrayList;
import java.util.List;

public class PaintView extends View {

    public class DrawPath {
        Path path;
        Paint paint;
    }

    private Paint paint;
    private Path path;
    private float downX, downY;
    private float tempX, tempY;
    private int paintWidth = 10;
    private List<DrawPath> drawPathList;
    private List<DrawPath> savePathList;

    public PaintView(Context context) {
        this(context, null);
    }

    public PaintView(Context context, AttributeSet attrs) {
        this(context, attrs, 0);
    }

    public PaintView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        drawPathList = new ArrayList<>();
        savePathList = new ArrayList<>();
        initPaint();
    }

    private void initPaint() {
        paint = new Paint();
        paint.setAntiAlias(true);
        paint.setStrokeWidth(paintWidth);
        paint.setStyle(Paint.Style.STROKE);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        if (drawPathList != null && !drawPathList.isEmpty()) {
            for (DrawPath drawPath : drawPathList) {
                if (drawPath.path != null) {
                    canvas.drawPath(drawPath.path, drawPath.paint);
                }
            }
        }
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                downX = event.getX();
                downY = event.getY();
                path = new Path();//每次手指下去都是一条新的路径
                path.moveTo(downX, downY);
                DrawPath drawPath = new DrawPath();
                drawPath.paint = paint;
                drawPath.path = path;
                drawPathList.add(drawPath);
                invalidate();
                tempX = downX;
                tempY = downY;
                break;
            case MotionEvent.ACTION_MOVE:
                float moveX = event.getX();
                float moveY = event.getY();
                path.quadTo(tempX, tempY, moveX, moveY);
                invalidate();
                tempX = moveX;
                tempY = moveY;
                break;
            case MotionEvent.ACTION_UP:
                initPaint();//每次手指抬起都要重置下画笔,不然画笔会保存了之前的设置什么画笔的属性会引起bug
                break;
        }
        return true;
    }

    /**
     * 撤销功能。
     */
    public void undo() {
        if (drawPathList != null && drawPathList.size() >= 1) {
            savePathList.add(drawPathList.get(drawPathList.size() - 1));
            drawPathList.remove(drawPathList.size() - 1);
            invalidate();
        }
    }

    /**
     * 反撤销功能。重新生效。
     */
    public void reundo() {
        if (savePathList != null && !savePathList.isEmpty()) {
            drawPathList.add(savePathList.get(savePathList.size() - 1));
            savePathList.remove(savePathList.size() - 1);
            invalidate();
        }
    }

    /**
     * 改变画笔颜色。
     *
     * @param color
     */
    public void resetPaintColor(int color) {
        paint.setColor(color);
    }

    /**
     * 放大就是改变画笔的宽度。线条变粗。
     */
    public void resetPaintWidth() {
        paintWidth += 2;
        paint.setStrokeWidth(paintWidth);
    }

    /**
     * 橡皮擦功能。
     * 原理是把画笔的颜色和view的背景颜色一样就,然后把画笔的宽度变大了,擦除的时候显得擦除范围大点。
     */
    public void eraser() {
        paint.setColor(Color.WHITE);//这是view背景的颜色
        paint.setStrokeWidth(paintWidth + 6);
    }
}

 

 

剩下的就是使用。写一个xml布局:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:id="@+id/activity_main"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:background="#ffffff">

    <RelativeLayout
        android:id="@+id/rl_left"
        android:layout_width="100dp"
        android:layout_height="match_parent">

        <Button
            android:id="@+id/btn_undo"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:text="撤销" />

        <Button
            android:id="@+id/btn_do"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_below="@id/btn_undo"
            android:text="反撤销" />

        <Button
            android:id="@+id/btn_red"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_below="@id/btn_do"
            android:text="红色" />

        <Button
            android:id="@+id/btn_blue"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_below="@id/btn_red"
            android:text="蓝色" />

        <Button
            android:id="@+id/btn_green"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_below="@id/btn_blue"
            android:text="绿色" />

        <Button
            android:id="@+id/btn_scral"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_below="@id/btn_green"
            android:text="放大" />

        <Button
            android:id="@+id/btn_eraser"
            android:layout_width="match_parent"
            android:layout_height="60dp"
            android:layout_below="@id/btn_scral"
            android:text="橡皮擦" />
    </RelativeLayout>

    <com.zhangphil.PaintView
        android:id="@+id/paint_view"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toRightOf="@id/rl_left" />
</RelativeLayout>

 

测试的Activity:

package zhangphil.test;

import android.graphics.Color;
import android.support.v7.app.AppCompatActivity;
import android.os.Bundle;
import android.view.View;
import android.widget.Button;

import com.zhangphil.PaintView;

public class DrawActivity extends AppCompatActivity implements View.OnClickListener {
    private Button btnUndo;
    private Button btnDo;
    private Button btnRed;
    private Button btnBlue;
    private Button btnGreen;
    private Button btnScral; //放大。
    private Button btnEraser; //橡皮擦。
    private PaintView paintView;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
        initListener();
    }

    private void initListener() {
        btnUndo.setOnClickListener(this);
        btnDo.setOnClickListener(this);
        btnRed.setOnClickListener(this);
        btnBlue.setOnClickListener(this);
        btnGreen.setOnClickListener(this);
        btnScral.setOnClickListener(this);
        btnEraser.setOnClickListener(this);
    }

    private void initView() {
        paintView = (findViewById(R.id.paint_view));
        btnUndo = findViewById(R.id.btn_undo);
        btnDo = findViewById(R.id.btn_do);
        btnRed = findViewById(R.id.btn_red);
        btnBlue = findViewById(R.id.btn_blue);
        btnGreen = findViewById(R.id.btn_green);
        btnScral = findViewById(R.id.btn_scral);
        btnEraser =  findViewById(R.id.btn_eraser);
    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
            case R.id.btn_undo:
                paintView.undo();
                return;
            case R.id.btn_do:
                paintView.reundo();
                return;
            case R.id.btn_red:
                paintView.resetPaintColor(Color.RED);
                return;
            case R.id.btn_green:
                paintView.resetPaintColor(Color.GREEN);
                return;
            case R.id.btn_blue:
                paintView.resetPaintColor(Color.BLUE);
                return;
            case R.id.btn_scral:
                paintView.resetPaintWidth();
                break;
            case R.id.btn_eraser:
                paintView.eraser();
                break;
        }
    }
}