2019独角兽企业重金招聘Python工程师标准>>>

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);}@Overridepublic 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();}}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:// 每次down下去重新new一个PathmPath = 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;}
}

转载于:https://my.oschina.net/meetthebetteryour/blog/813942

画布上涂鸦功能(可橡皮擦、可清除)相关推荐

  1. 巧用canvas实现画板功能,使用画笔在图片上涂画,橡皮擦可擦除涂画,并保存

    canvas 是HTML5的元素,使用JavaScript 在网页上绘制图像. canvas 拥有多种绘制路径.矩形.圆形.字符以及添加图像的方法. 而如果想实现画笔在画板涂画画笔在图片上涂画,橡皮擦 ...

  2. 从web编辑器 UEditor 中单独提取图片上传,包含多图片单图片上传以及在线涂鸦功能...

    UEditor是由百度web前端研发部开发所见即所得富文本web编辑器,具有轻量,可定制,注重用户体验等特点,开源基于MIT协议,允许自由使用和修改代码.(抄的...) UEditor是非常好用的富文 ...

  3. Android实现涂鸦功能

    1.自定义View,用来涂鸦,签名 /** * 自定义View * @author VanishMagic * */ public class DrawView extends View{ //笔触当 ...

  4. android 图片字体涂鸦,android 涂鸦功能

    项目突然用到涂鸦的功能,网上的Demo背景都是空白的,还有好多BUG,就自己搞了一个,好了不多说了,进入正题,所谓涂鸦就是利用安卓的绘画功能在画布上进行操作,直接上代码吧 /** *初始化组件 */ ...

  5. php 涂鸦,微信小程序涂鸦功能的实现

    本文主要介绍了微信小程序实现的涂鸦功能,涉及微信小程序事件响应及画笔的相关操作技巧,并附带源码供读者下载参考,需要的朋友可以参考下,希望能帮助到大家. 先来看看运行效果: 布局文件index.wxml ...

  6. 基于canvas剪辑区域功能实现橡皮擦效果

    这篇文章主要介绍了基于canvas剪辑区域功能实现橡皮擦效果,非常不错,具有参考借鉴价值,需要的朋友可以参考下 这是基础结构 没什么好说的 ?<!DOCTYPE html> <htm ...

  7. android涂鸦板保存功能,Android 使用Path实现涂鸦功能

    今天实现一个涂鸦效果,会分几步实现,这里有一个重要的知识点就是图层,要理解这个,不然你看这篇博客,很迷茫,迷茫的苍茫的天涯是我的爱,先从简单的需求做起,绘制一条线,代码如下: package com. ...

  8. html5 jquery paint plugin,5+最好的画板,并在画布上手动绘制JavaScript和jQuery插件

    本文概述 从定制的签名板到我们的MsPaint个人网络版本, 如果你想进入很棒的画布世界, 这些库都是一个不错的开始.根据实现的难易程度以及API与开发人员之间的友好程度(包括依赖关系)来进行排名. ...

  9. linux手写涂鸦代码,canvas实现图片涂鸦功能(附代码)

    本篇文章给大家带来的内容是关于canvas实现图片涂鸦功能(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助. 需求需要对图片进行标注,导出图片. 需要标注N多图片最后同时保存. ...

最新文章

  1. linux 文本搜索命令 grep egrep fgrep 区别
  2. Asp.Net Core异常处理整理
  3. 今年双 11,阿里业务 100% 上云,云原生有哪些技术亮点?
  4. 批处理命令 / set
  5. 详解CSS的盒模型(box model) 及 CSS3新增盒模型计算方式box-sizing
  6. JAVA类与对象(一)----基础概念理解
  7. Flutter 是移动应用程序开发的未来?
  8. pytorch:定义自己的网络结构
  9. android上传图片失败问题
  10. 修改DevExpress中英文提示,将英文改为中文
  11. 如果站做的比较大,那么关键词和内页的分布就要比别人高一个档次
  12. 软考高级 真题 2017年上半年 信息系统项目管理师 论文
  13. stm32 c语言 位带,我对STM32所用位带操作宏的超详细剖析、优势分析及应用推广探索研究(持续更新,欢迎讨论交流)...
  14. 当当网,京东商城,一号店,苏宁易购百万数据抓取爬虫程序
  15. 【颜纠日记】祛痘广告那么神?分享确切的祛痘方式。
  16. 添加w3c验证图片到网站
  17. java image 内存不足_java内存不足的解决方法
  18. 孙子算经-秦王暗点兵问题
  19. 实验十 基于Simulink的爬山法MPPT技术仿真
  20. Java实现“梭哈”游戏

热门文章

  1. Python中functools模块函数解析
  2. Hello TensorFlow
  3. [Effective JavaScript 笔记]第27条:使用闭包而不是字符串来封装代码
  4. 解决“The executable was signed with invalid entitlements.”问题
  5. (转)游戏程序员养成计划 (更新2010.11.6)
  6. 链接生成动态二维码图片显示在页面上
  7. bookkeeper源码解析
  8. Reactor网络编程模型
  9. java jlabe_[求助]JPanel上怎么移除JLabe。l
  10. 调节pycharm字体大_字体美化大师里的字体推荐