美文网首页
Android 编辑图片 Canvas画图,涂鸦,马赛克等(一)

Android 编辑图片 Canvas画图,涂鸦,马赛克等(一)

作者: BigP | 来源:发表于2019-02-25 17:40 被阅读0次

需求功能详解

单纯的编辑图片的功能,能够在界面上进行图形的绘制,线条的涂鸦,和画马赛克的绘制,并且有撤销的功能。话不多说,直接看一下效果吧:


图片编辑效果

主要实现思路

实现一个自定义View,重写onDraw(),集成这些编辑功能。

  • 功能集成
    该编辑功能有涂鸦,画图形,画文字,和马赛克的功能,这里只对除了文字的内容进行介绍,若想进一步获得文字功能,可在代码库中pull代码,并自己打开该功能:
public enum MODE {
    NONE, GRAPH_MODE, DOODLE_MODE, MOSAIC_MODE, DRAG, ZOOM
}
  • 涂鸦
    先说最简单的涂鸦吧,涂鸦功能实际就是在界面上画线,路径跟着手指移动就完事了。由于有撤销的功能,所以需要把Path都保存起来,在按下时new Path(),并且moveTo按下的位置,在手指移动过程中,将这条path lineTo相对应的位置,手指抬起时结束,那么一条路径不就画完了吗!
    /**
     * 涂鸦的路径
     */
    private ArrayList<DrawPathBean> mDoodlePath = new ArrayList<>();

涂鸦功能的实例:

/**
 * 记录画笔和画图的路径,主要用来撤销画图的操作
 */
class DrawPathBean {
    public Path path;
    public Paint paint;
    public MODE mode;

    DrawPathBean(Path path, Paint paint, MODE mode) {
        this.paint = paint;
        this.path = path;
        this.mode = mode;
    }
}

为了之后的撤销操作,需要将路径记录下来。
Action_Down中新建画笔和路径,并添加到List中,

// 设置对应mode的画笔
setModePaint(mMode);
mTempPath = new Path();

mStartX = mMoveX;
mStartY = mMoveY;
mTempPath.moveTo(mStartX, mStartY);

// 把path加到队列中
DrawPathBean pathBean = new DrawPathBean(mTempPath, mTempPaint, mMode);
mPaths.add(mMode);
if (mMode == MODE.DOODLE_MODE) {
mDoodlePath.add(pathBean);
} else if (mMode == MODE.MOSAIC_MODE) {
mMosaicPath.add(pathBean);
}

Action_Move时,只要将最后一条路径的path读取出来,移动到手指所到的位置即可:

if (mMode == MODE.DOODLE_MODE && mDoodlePath.size() > 0) {
    mDoodlePath.get(mDoodlePath.size() - 1).path.lineTo(mMoveX, mMoveY);
}

然后在Action_Up的时候,将临时的路径和画笔变量清空,即可:

mTempPath = null;
mTempPaint = null;

最后一步:onDraw()中,将该数组中保存的路径绘制出来:

if (mDoodlePath.size() > 0) {
    for (DrawPathBean pathBean : mDoodlePath) {
        canvas.drawPath(pathBean.path, pathBean.paint);
    }
}
  • 撤销
    有了路径,那么撤销操作就很简单了,只要将数组中最后一条清除,再重绘界面,那么撤销操作就完成了。这里的代码综合了所有操作的撤销动作,涂鸦的只需要看Doodle相关即可:
/**
* 撤销操作
*
* @return 撤销后剩余可以撤销的步骤
*/
public int revertPath() {
    int size = mPaths.size();
    if (size > 0) {
        // 根据最后一位数的mode,删除对应path
        MODE lastestMode = mPaths.get(size - 1);
        if (lastestMode == MODE.DOODLE_MODE && mDoodlePath.size() > 0) {
            mDoodlePath.remove(mDoodlePath.size() - 1);
        } else if (lastestMode == MODE.MOSAIC_MODE && mMosaicPath.size() > 0) {
            mMosaicPath.remove(mMosaicPath.size() - 1);
        } else if (lastestMode == MODE.GRAPH_MODE && mGraphPath.size() > 0) {
            mGraphPath.remove(mGraphPath.size() - 1);
        }
        mPaths.remove(size - 1);
    }
    postInvalidate();
    return size;
}

mPath是三种路径的总和,不管是涂鸦,图形,或是马赛克,都需要将该操作存入mPath,然后撤销时,根据存入的类型,对该类型的路径进行相对应的撤销操作。
至此,一个完整的涂鸦功能就完成了~

相关文章

网友评论

      本文标题:Android 编辑图片 Canvas画图,涂鸦,马赛克等(一)

      本文链接:https://www.haomeiwen.com/subject/eioeyqtx.html