关于Android的Doodle涂鸦插件深度解析

项目需要,涂鸦功能。但不仅仅需要其基础功能,需要在此基础上二次开发。

但Doodle的介绍相对比较简介,不深入研读、测试、修改不能了解其精髓。故而以记录此文,用于辅助理解代码,或有瑕疵或不对地方 望谅解。

本文主要从架构和代码层级:类函数角度分析代码。

Doodle 的git地址:https://github.com/1993hzw/Doodle

几篇不错的原理解析。

Android涂鸦画板原理详解——从初级到高级(一)_android涂鸦原理-CSDN博客

Android涂鸦画板原理详解——从初级到高级(二)_画画涂鸦游戏原理-CSDN博客

涂鸦框架的优化——解决绘制时的卡顿问题,纵享丝滑_flutter的gridview网格实现涂鸦很慢-CSDN博客

一、代码设计框架图:

二、Doodle Coordinate 涂鸦坐标 

三、Canvas drawText原理图

四、DoodleView代码分析

初始化调用方式

mDoodle = mDoodleView = new DoodleViewWrapper(this, bitmap, mDoodleParams.mOptimizeDrawing, new IDoodleListener() {...........}

IDoodleListener回调方法如下:

onSaved()  生成的图片保存等

onReady() 初始化设置、字体大小、颜色等

onError() 错误回调

ForegroundView //前景图层,每次刷新都会绘制,用于绘制正在创建或选中的item

绘制逻辑初步看为:items的遍历循环,然后执行drawAtTheTop ,此方法为画在所有item的上面 标注实则只有一个。在创建标注时添加addItem

BackgroundView // 背景图层,只在背景发生变化时绘制, 用于绘制原始图片或在优化绘制时的非编辑状态的item

Init()方法:参数bitmap(背景图片大小 这里可以限制住标注的图片大小范围)传入,对其与手机的屏幕宽高进行对比,并对图片居中显示,缩放率(屏幕相对图片的尺寸mCentreScale)、水平或垂直下的 图片距离屏幕边距长度mCentreTranX/Y、初始设置字体大小mSize(通过 屏幕分辨率(dp2px)/缩放率mCentreScale)

其他还封装了大量方法,用于处理:   

将屏幕触摸坐标x转换成在图片中的坐标

  将图片坐标x转换成屏幕触摸坐标

  坐标换算

  刷新界面refresh

.......

五、DoodleText代码分析:

父类子类之间嵌套关系

DoodleText extends DoodleRotatableItemBase extends DoodleSelectableItemBase extends DoodleItemBase implements IDoodleSelectableItem extends IDoodleItem

resetBounds 即 mRect(DoodleSelectableitemBase) 其内逻辑为 DoodleText实现子方法中重新获取size然后衡量text文字的矩形大小和偏移位置(offset(0,mRect.Height))

setLocation

resetBoundsScaled

doDraw(Canvas canvas):绘制文字、平移画布:根据mScale 和 文字的高度进行平移。

PointF mLocation用于记录 text的边框左顶点。

mPivotX, mPivotY用于记录text的文字中心坐标

变化标注位置:DoodleText.setLayout(x,y)

改变标注大小:DoodleText.setSize(会改变中心点 初始的时候设置一次就够了)

改变标注颜色:DoodleText.setColor()

toX/Y()  用于将屏幕触摸坐标x转换成在图片中的坐标

doDraw():此方法负责绘制文字

六、DoodleOnTouchGestureListener类解析:

手势监听器 对于手指滑动屏幕的方向增减:快速滑动和缓慢滑动,增减量是有差异

                  

Adapter或者Activity初始化屏幕点击或滑动事件监听

IDoodleTouchDetector detector = new DoodleTouchDetector(getApplicationContext(), mTouchGestureListener);

mDoodleView.setDefaultTouchDetector(detector);

 mTouchGestureListener = new DoodleOnTouchGestureListener(mDoodleView, new DoodleOnTouchGestureListener.ISelectionListener() {.............}

onSelectedItem()回调IDoodleSelectableItem选中的状态变化。用于处理外部的界面UI变化

onScroll、onScrollEnd、onScrollBegin用于响应处理 涂鸦的画线

onScroll 处理移动操作,需先判断是否有选中item

mDoodle.setDoodleScale()用于为选中情况下 背景图片的缩放。

焦点改变后:双指触摸并移动图片进行平移:mDoodle.setDoodleTranslationX/Y()

onSingleTapUp 用于判断是否选中目标,从而显示或隐藏选中的边框。

其操作在DoodleText逻辑为 单击屏幕抬起后若无被选中且处于编辑状态回调onCreateSelectableItem, 执行createDoodleText(null,x,y)  X,Y为转换后相对于图片的坐标

onScrollBegin:其内有关于旋转逻辑的判断:触摸点是否在旋转的范围内

双指缩放原理

DoodleOnTouchGestureListener 继承的父类TouchGestureDetector.OnTouchGestureListener

其中的onScale方法

为Doodle其他一个封装库 andorids 增量的增加和较少缩放比例值。初始1.0

额外封装的 源码 没有时间去研读了。原理待补充

七、DoodleRotatableItemBase类代码解析:

doDrawAtTheTop: 其内为绘制方框显示/隐藏 包括旋转的画线和小圈。

CanRotate(x,y): 用于判断是否触摸点 触摸到旋转的画线和小圈范围,此判断从DoodleOnTouchGestureListener的 onScrollBegin事件逻辑判断

八、DoodleItemBase类代码解析:

mScale    缩放倍数,围绕(PivotX,PivotY)旋转即中心值坐标,默认缩放值1.0f.控制画布的大小,即视觉上字体的大小。

draw(Canvas canvas) 处理旋转坐标、缩放、平移:

canvas.scale(mScale, mScale, px, py); // 缩放

这里自己加了限制逻辑,缩放过程中的左右和上下限制过界问题。

九、DoodleSelectableItemBase类代码解析:

ITEM_PADDING 绘制item矩形区域时增加的padding

getUnitSize(IDoodle) 获取当前涂鸦坐标系中的单位大小,该单位参考dp,独立于图片

limitBound 限定边界

Refresh() 用于DoodleView的 refresh实现,刷新前层view

十、涂鸦保存图片的逻辑

业务逻辑层:mDoodle.save() DoodleView中执行save()方法。原理使用AsyncTask线程执行图片的绘制:refreshDoodleBitmap其内遍历所有的文字标注,分别执行draw()和 drawAtTheTop()(

十一、涂鸦指定的文字标注删除逻辑:

1.去除选中的item

mDoodle.removeItem(mTouchGestureListener.getSelectedItem());

方法执行到doodleView的 removeItem实现类:把分层的View内item删除。( 这些item绘制在View的画布上,而不是在图片Bitmap.比如正在创建或选中的item)

与此相关联>>新增方法:DoodleOnTouchGestureListener 的onRemoveSelectedItem 方法上传到最顶部调用处理,主要为删除item相关逻辑

2.设置选中的item为空

mTouchGestureListener.setSelectedItem(null);

  • 19
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值