毛笔功能的实现

主页面MainActivityprivate MyView myView;private Button syk_button_back;private Button syk_button_blakgd;private Button syk_button_clear;private Button syk_button_colorpen;private Button syk_button_fouse;private RelativeLayout syk_drawbitmap;private int c;@Overrideprotected void initLayout() {setContentView(R.layout.activity_main);}@Overrideprotected void findViewById() {myView = (MyView)findViewById(R.id.palette);syk_drawbitmap = (RelativeLayout)findViewById(R.id.syk_drawbitmap);syk_button_back = (Button) findViewById(R.id.syk_button_back);syk_button_blakgd = (Button) findViewById(R.id.syk_button_blakgd);syk_button_clear = (Button) findViewById(R.id.syk_button_clear);syk_button_fouse = (Button) findViewById(R.id.syk_button_fouse);}@Overrideprotected void onClickEvent(View paramView) {switch (paramView.getId()) {case R.id.syk_button_back:myView.setBack();break;case R.id.syk_button_clear:ShowDialog();break;case R.id.syk_button_fouse:myView.setForward();break;default:break;}}@Overridepublic boolean onTouchEvent(MotionEvent event) {/*if(event.getY()>400){syk_button_pensize.onTouchEvent(event);}*/return myView.onTouchEvent(event);}public void ShowDialog(){AlertDialog.Builder builder=new AlertDialog.Builder(MainActivity.this);builder.setTitle("你即将清空画布,将不能返回!");builder.setPositiveButton("确定", new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {// TODO Auto-generated method stubmyView.setClear();}});builder.setNegativeButton("取消",new DialogInterface.OnClickListener() {@Overridepublic void onClick(DialogInterface dialog, int which) {}});builder.create().show();}@Overrideprotected void onDestroy() {super.onDestroy();}@Overrideprotected void setListener() {syk_button_back.setOnClickListener(this);syk_button_blakgd.setOnClickListener(this); syk_button_clear .setOnClickListener(this);syk_button_fouse.setOnClickListener(this);}@Overrideprotected void initOthers() {// TODO Auto-generated method stub}}自定义的Viewpublic class MyView extends SurfaceView implements Runnable,SurfaceHolder.Callback {SurfaceHolder mSurfaceHolder = null;private ArrayList actionList = null;private int currentColor = Color.BLACK;private int currentSize = 3;private Action curAction = null;Bitmap tembit = null;boolean mLoop = true;private int bgBitmapX = 0;private int bgBitmapY = 0;private int bgBitmapHeight = 400;private int bgBitmapWidth = 400;private int currentPaintTool = 1;// 绘图区背景图片Bitmap bgBitmap = null;// 记录动作在集合中的角标private int currentPaintIndex = -1;private Paint mPaint;// 返回按钮的控制boolean isBackPressed;boolean isForwardPressed;// 清屏boolean isClearPressed;// 自定义毛笔路径private BrushPath mPath = new BrushPath();private Canvas canvasTemp;private Context mcontext;private int width;private int heght;public MyView(Context context, AttributeSet arr) {super(context, arr);this.mcontext = context;this.width = 320;this.heght = 480;mPaint = new Paint();actionList = new ArrayList();mSurfaceHolder = this.getHolder();mSurfaceHolder.addCallback(this);this.setFocusable(true);mLoop = true;loadBitmap();new Thread(this).start();}// 加载图片public void loadBitmap() {try {InputStream is = getResources().openRawResource(R.drawable.pic1);bgBitmap = BitmapFactory.decodeStream(is);} catch (Exception e) {}}@Overridepublic void run() {while (mLoop) {try {Thread.sleep(50);} catch (InterruptedException e) {e.printStackTrace();}synchronized (MyView.this) {Draw();}}}public void setwh(int w, int h) {width = w;heght = h;}public void setcurrentSize(int size) {currentSize = size;}public void setcurrentPaintTool(int tool) {currentPaintTool = tool;}public void setPaintColor(int color) {currentColor = color;}public void setBgBitmap(Bitmap b) {bgBitmap = b;new Thread(this).start();}@Overridepublic boolean onTouchEvent(MotionEvent event) {float x = event.getX();float y = event.getY();switch (event.getAction()) {case MotionEvent.ACTION_DOWN:curAction = new MyMaoBi(x, y, 8, currentColor);mPath.onTouchDown(x, y);curAction.setPath(mPath);clearSpareAction();break;case MotionEvent.ACTION_MOVE:float x1 = event.getX();float y1 = event.getY();mPath.onTouchMove(x1, y1);curAction.setPath(mPath);if (curAction != null) {curAction.move(x, y);}break;case MotionEvent.ACTION_UP:mPath.onTouchUp(x, y);curAction.setPath(mPath);if (curAction != null) {curAction.move(x, y);}actionList.add(curAction);currentPaintIndex++;curAction = null;break;}return super.onTouchEvent(event);}@Overrideprotected void onDraw(Canvas canvas) {super.onDraw(canvas);}private void Draw() {Canvas canvas = mSurfaceHolder.lockCanvas();if (mSurfaceHolder == null || canvas == null) {return;}canvas.drawColor(Color.WHITE);drawMainPallent(canvas);mSurfaceHolder.unlockCanvasAndPost(canvas);}// 画主画板private void drawMainPallent(Canvas canvas) {// 设置画笔没有锯齿,空心mPaint.setAntiAlias(true);mPaint.setStyle(Paint.Style.STROKE);// 画板绘图区背景图片canvas.drawBitmap(bgBitmap, bgBitmap.getWidth(), bgBitmap.getHeight(),null);// tembit = Bitmap.createBitmap(bgBitmap.getWidth(), 480,// Config.ARGB_4444);tembit = Bitmap.createBitmap(320, 480, Config.ARGB_4444);canvasTemp = new Canvas(tembit);if (isClearPressed) {canvasTemp.drawColor(Color.TRANSPARENT);return;}canvasTemp.drawColor(Color.TRANSPARENT);for (int i = 0; i <= currentPaintIndex; i++) {actionList.get(i).draw(canvasTemp);}// 画当前画笔痕迹if (curAction != null) {curAction.draw(canvasTemp);}// 在主画板上绘制临时画布上的图像canvas.drawBitmap(tembit, bgBitmapX, bgBitmapY, null);// 画板绘图区边框}// 返回public void setBack() {if (isBackPressed) {return;}if (currentPaintIndex >= 0) {isBackPressed = true;currentPaintIndex--;Draw();isBackPressed = false;}}// 前进public void setForward() {if (isForwardPressed) {return;}if ((currentPaintIndex + 1) < actionList.size()) {isForwardPressed = true;currentPaintIndex++;Draw();isForwardPressed = false;}}// 清屏public void setClear() {if (isClearPressed) {return;}isClearPressed = true;clearSpareAction();currentPaintIndex = -1;isClearPressed = false;}@Overridepublic void surfaceChanged(SurfaceHolder arg0, int arg1, int arg2, int arg3) {}@Overridepublic void surfaceCreated(SurfaceHolder arg0) {new Thread(this).start();}@Overridepublic void surfaceDestroyed(SurfaceHolder arg0) {clearSpareAction();mLoop = false;}// 后退前进完成后,缓存的动作private void clearSpareAction() {for (int i = actionList.size() - 1; i > currentPaintIndex; i--) {actionList.remove(i);}}}毛笔路径类,不断在每个点周围加上4个个点,算出幅度,进行绘制毛笔效果的路径 public class BrushPath {// 当前路径上的点集合private ArrayList<ArrayList> mPath;// 已完成的路径private Path path;// 线条间的宽度private float width = 0.5f;// 画笔是否移动private boolean isMove = false;// 圆的边界框private RectF rect;/** * 构造方法 */public BrushPath() {rect = new RectF();path = new Path();mPath = new ArrayList<ArrayList>();mPath.add(new ArrayList());mPath.add(new ArrayList());mPath.add(new ArrayList());mPath.add(new ArrayList());mPath.add(new ArrayList());}/** * 设置 path 对象路径 */private void setPath() {// 路径清空 path.reset();if (!mPath.get(0).isEmpty()) {// 局部变量PointF point, p1, p2 = new PointF();//点的集合,遍历for (int i = 0; i < mPath.size(); i++) {point = mPath.get(i).get(0);//移到第一个点,path.moveTo(point.x, point.y);for (int j = 1; j < mPath.get(i).size() - 1; j++) {p1 = mPath.get(i).get(j - 1);p2 = mPath.get(i).get(j);//移到到指定位置path.quadTo(p1.x, p1.y, (p1.x + p2.x) / 2,(p1.y + p2.y) / 2);}path.lineTo(mPath.get(i).get(mPath.get(i).size() - 1).x, mPath.get(0).get(mPath.get(0).size() - 1).y);}}}// 获取路径public Path getPath() {if (isMove == false) {path.reset();//添加椭圆形路径 path.addOval(rect, Direction.CW);return path;}// 设置 path 对象路径setPath();return new Path(path);}// 画出路径public void drawPath(Canvas canvas, Paint paint) {// 设置 path 对象路径setPath();canvas.drawPath(path, paint);}// 触摸按下事件public void onTouchDown(float x, float y) {isMove = false;for (int i = 0; i < mPath.size(); i++) {mPath.get(i).clear();mPath.get(i).add(new PointF(x, y));}}// 触摸弹起事件public void onTouchUp(float x, float y) {for (int i = 0; i < mPath.size(); i++) {mPath.get(i).add(new PointF(x, y));}if (isMove == false) {int offset = 2;rect.left = x + offset;rect.top = y + offset;rect.right = x - offset;rect.bottom = y - offset;}width = 0.5f;}// 触摸移动事件public void onTouchMove(float x, float y) {isMove = true;mPath.get(0).add(new PointF(x, y));// 线段上的第一个点元素PointF p1 = mPath.get(0).get(mPath.get(0).size() - 1);// 线段上的第二个点元素PointF p2 = mPath.get(0).get(mPath.get(0).size() - 2);// 得到两点间线段与x轴的夹角 if(p1.equals(p2.x, p2.y)) return; double rad = getRad(p1, p2);if (width < 1.5f) {width += 0.1f;}addPoint(p1, rad, width);}// 向当前笔画中添加新点private void addPoint(PointF p, double rad, float width) {PointF p3, p4, p5, p6;// 左右两侧的点p3 = getOnCerclePoint(p, width * 1, rad - 90 * Math.PI / 180);p4 = getOnCerclePoint(p, width * 2, rad - 90 * Math.PI / 180);p5 = getOnCerclePoint(p, width * 1, rad + 90 * Math.PI / 180);p6 = getOnCerclePoint(p, width * 2, rad + 90 * Math.PI / 180);// 添加点mPath.get(1).add(p3);mPath.get(2).add(p4);mPath.get(3).add(p5);mPath.get(4).add(p6);}public void clear() {for (int i = 0; i < mPath.size(); i++) {mPath.get(i).clear();}}/** * 获得两点间距离 * * @param p1 * @param p2 * @return */public int getLen(PointF p1, PointF p2) {double len = Math.sqrt(Math.pow(p1.x - p2.x, 2)+ Math.pow(p1.y - p2.y, 2));return (int) len;}/** * 得到在圆上的一个点,指定角度和半径的点 * * @param center * @param r * @param rad * @return */private PointF getOnCerclePoint(PointF center, float r, double rad) {PointF point = new PointF();point.x = (float) (center.x) + (float) (r * Math.cos(rad));point.y = (float) (center.y) + (float) (r * Math.sin(rad));return point;}/** * 得到两点之间的弧度 * * @param p1 * @param p2 * @return */protected double getRad(PointF p1, PointF p2) {// 得到两点X的距离float x = p2.x - p1.x;// 得到两点Y的距离float y = p2.y - p1.y;// 算出斜边长float xie = (float) Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));// 得到这个角度的余弦值(通过三角函数中的定理 :邻边/斜边=角度余弦值)float cosAngle = x / xie;// 通过反余弦定理获取到其角度的弧度float rad = (float) Math.acos(cosAngle);// 注意:当触屏的位置Y坐标<摇杆的Y坐标我们要取反值-0~-180if (p2.y < p1.y) {rad = -rad;}return rad;}}毛笔绘制动作类public class Action {public int color;Action() {color = Color.BLACK;}Action(int color) {this.color = color;}public void draw(Canvas canvas) {}public void move(float mx, float my) {}public void setPath(BrushPath p) {// TODO Auto-generated method stub}}class MyMaoBi extends Action {BrushPath mpath;int size;private Path path;MyMaoBi() {mpath = new BrushPath();path = new Path();size = 1;}MyMaoBi(float x, float y, int size, int color) {super(color);path = new Path();this.size = size;path.moveTo(x, y);path.lineTo(x, y);}public void draw(Canvas canvas) {Paint paint = new Paint();paint.setAntiAlias(true);paint.setDither(true);paint.setColor(Color.BLACK);paint.setStrokeWidth(size);BlurMaskFilter mBlur = new BlurMaskFilter(size / 2.0f,BlurMaskFilter.Blur.INNER);paint.setMaskFilter(mBlur);paint.setStyle(Paint.Style.STROKE);paint.setStrokeJoin(Paint.Join.ROUND);paint.setStrokeCap(Paint.Cap.ROUND);// setPath(p);canvas.drawPath(path, paint);}public void setPath(BrushPath p) {path.addPath(p.getPath());}public void move(float mx, float my) {path.lineTo(mx, my);}}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
出售毛笔算法 前十名顾客低价200元,采用C++编写的纯算法,底层封装了CMyPen类,含有4笔,分别是毛笔,画笔,荧光笔,水笔. 非常容易调用,只用响应鼠标消息,将点加入进去即可。 纯粹底层算法,兼容windows xp,windows vista ,windows7 ,也很容易向其他语言移植,例如C#,.net,java,易语言等 联系方式 跃天 Tel 18674059458 QQ 1906733710 E-Mail [email protected] 同时销售下面店铺中的 电子签到源码:前5名顾客800元 电子白板源码:前10名顾客600元 遇到就是赚到 如不要源码,购买软件均300元 淘宝链接 :http://item.taobao.com/item.htm?id=15205465505 如何将毛笔功能添加到你的代码中 在你窗口类的头文件中声明 ................................................. .h ............................................... CDC m_MemDC;//用于绘制画笔的背景,可以填充背景色或者背景图 CMyPen m_myPen; //主要类成员,笔的算法类 ................................................cpp ............................................................ 1初始化 在创建窗口下,如果是MFC程序,一般在 OnInitDlg 对话框 或者OnInitialUpdate 文档应用类下 m_MemDC.CreateCompatibleDC(GetDC()); m_myPen.SetDibTarget(&m_MemDC, m_nWidth, m_nHeight);//设置你笔绘画的有效区的宽度和高度 m_myPen.SetPenType(CMyPen::PT_MAOBI);//设置笔的类型 这里是毛笔,还有画笔,荧光笔,水笔 m_myPen.SetWidth(9);//指定笔的宽度 m_myPen.SetBGColor(RGB(240,240,240));//用与指定背景色,也可以指定背景图 // m_myPen.SetBkImageFromWnd(lpszPath);//指定背景图 m_myPen.SetColor(RGB(0,0,0));// 用于指定笔的颜色 m_myPen.Clear();//擦除并刷新 2 响应OnPait或者OnDraw void CXXXXView::OnDraw(CDC* pDC) { CDrawProDoc* pDoc = GetDocument(); ASSERT_VALID(pDoc); if (!pDoc) return; pDC->BitBlt(0,0, m_nWidth, m_nHeight, &m_MemDC, 0, 0, SRCCOPY);//需要添加此句 } 3 响应OnMouse 在OnLButtonDown(UINT nFlags, CPoint point)下加入 m_myPen.PushStart(point);//添加一笔的起始点 OnLButtonUp(UINT nFlags, CPoint point) m_myPen.PushEnd(point);//添加一笔的结束点 OnMouseMove(UINT nFlags, CPoint point) if( (nFlags&MK;_LBUTTON))//如果鼠标按下且移动 { m_myPen.Push(point);//添加中间点 InvalidateRect(rect .FALSE);//刷新区域 } 4 如何擦除所绘制的痕迹 m_myPen.Clear(); Invalidate(FALSE); 按照上述4步,你购买了代码就很实现毛笔功能了哦!于此同时,还有另外3笔,你将m_myPen.SetPenType(CMyPen::PT_MAOBI)改改就行了哦!

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值