Android简单实现画图功能
程序员文章站
2024-02-26 18:10:04
如何在图片上画画呢?这里写了一个demo,供大家参考
一、先看一眼工程结构
工程结构:
二、自定义view
这个自定义view实现了保留轨迹的功能,代码如下...
如何在图片上画画呢?这里写了一个demo,供大家参考
一、先看一眼工程结构
工程结构:
二、自定义view
这个自定义view实现了保留轨迹的功能,代码如下
package picturegame.view; import android.content.context; import android.graphics.bitmap; import android.graphics.bitmapfactory; import android.graphics.canvas; import android.graphics.color; import android.graphics.paint; import android.graphics.paint.style; import android.util.attributeset; import android.view.motionevent; import android.view.view; import com.winton.picturegame.r; public class gameview extends view{ private paint paint = null; // private bitmap originalbitmap = null;//原始图 private bitmap new1bitmap = null; private bitmap new2bitmap = null; private float clickx =0; private float clicky=0; private float startx=0; private float starty=0; private boolean ismove = true; private boolean isclear = false; private int color =color.red;//默认画笔颜色为红色 private float strokewidth =2.0f;//默认画笔粗度 public gameview(context context) { this(context,null); // todo auto-generated constructor stub } public gameview(context context,attributeset atts) { this(context,atts,0); // todo auto-generated constructor stub } public gameview(context context,attributeset atts,int defstyle) { super(context,atts,defstyle); // todo auto-generated constructor stub originalbitmap = bitmapfactory.decoderesource(getresources(), r.drawable.default_pic).copy(bitmap.config.argb_8888, true);//加载一张背景 new1bitmap=originalbitmap.createbitmap(originalbitmap); } //清除函数 public void clear(){ isclear =true; new2bitmap=originalbitmap.createbitmap(originalbitmap); invalidate();//重载 } public void setstrokewidth(float width){ this.strokewidth=width; initpaint(); } @override protected void ondraw(canvas canvas) { // todo auto-generated method stub super.ondraw(canvas); canvas.drawbitmap(writer(new1bitmap),0,0, null); } @override public boolean ontouchevent(motionevent event) { // todo auto-generated method stub clickx =event.getx(); clicky=event.gety(); if(event.getaction()==motionevent.action_down){ ismove =false; invalidate(); return true; } else if(event.getaction()==motionevent.action_move){ ismove =true; invalidate(); return true; } return super.ontouchevent(event); } /** * @title: writer * @description: todo(生成bitmap) * @param @param pic * @param @return 设定文件 * @return bitmap 返回类型 * @throws */ public bitmap writer(bitmap pic){ initpaint(); canvas canvas =null; if(isclear){ canvas=new canvas(new2bitmap); }else{ canvas=new canvas(pic); } if(ismove){ canvas.drawline(startx, starty, clickx, clicky, paint);//划线 } startx = clickx; starty =clicky; if(isclear){ return new2bitmap; } return pic; } private void initpaint(){ paint = new paint();//新建画笔 paint.setstyle(style.stroke);//设置为画线 paint.setantialias(true);//可以让线条圆滑一些 paint.setcolor(color);//设置画笔颜色 paint.setstrokewidth(strokewidth);//设置画笔线条的粗细 } /** * @title: setcolor * @description: todo(设置线条颜色的对外接口) * @param @param color 设定文件 * @return void 返回类型 * @throws */ public void setcolor(int color){ this.color=color; initpaint(); } }
三、主页面布局文件
主页面布局文件
<linearlayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center_horizontal" android:orientation="vertical" > <linearlayout android:layout_width="match_parent" android:layout_height="50dp" android:orientation="horizontal" > <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <textview android:id="@+id/tv_30" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/bg_notifaction" /> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <textview android:id="@+id/tv_25" android:layout_width="25dp" android:layout_height="25dp" android:background="@drawable/bg_notifaction" /> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <textview android:id="@+id/tv_20" android:layout_width="20dp" android:layout_height="20dp" android:background="@drawable/bg_notifaction" /> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <textview android:id="@+id/tv_15" android:layout_width="15dp" android:layout_height="15dp" android:background="@drawable/bg_notifaction" /> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <textview android:id="@+id/tv_10" android:layout_width="10dp" android:layout_height="10dp" android:background="@drawable/bg_notifaction" /> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <textview android:id="@+id/tv_5" android:layout_width="5dp" android:layout_height="5dp" android:background="@drawable/bg_notifaction" /> </linearlayout> <linearlayout android:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <textview android:id="@+id/tv_2" android:layout_width="2dp" android:layout_height="2dp" android:background="@drawable/bg_notifaction" /> </linearlayout> </linearlayout> <picturegame.view.gameview android:layout_width="match_parent" android:layout_height="300dp" android:id="@+id/gameview" /> <button android:layout_width="200dp" android:layout_height="80dp" android:text="clear" android:textcolor="@color/black" android:id="@+id/btn_clear" /> </linearlayout>
四、主activity代码
package com.winton.picturegame; import picturegame.view.gameview; import android.os.bundle; import android.view.view; import android.view.view.onclicklistener; import android.widget.button; import android.widget.textview; import com.winton.basemodule.baseactivity; public class mainactivity extends baseactivity implements onclicklistener { private gameview gameview = null; private button clear = null; private textview tv30,tv25,tv20,tv15,tv10,tv5,tv2; @override protected void oncreate(bundle savedinstancestate) { // todo auto-generated method stub super.oncreate(savedinstancestate); } @override public void initview() { // todo auto-generated method stub setcontentview(r.layout.activity_main); gameview=(gameview)findviewbyid(r.id.gameview); clear =(button)findviewbyid(r.id.btn_clear); tv30=(textview)findviewbyid(r.id.tv_30); tv25=(textview)findviewbyid(r.id.tv_25); tv20=(textview)findviewbyid(r.id.tv_20); tv15=(textview)findviewbyid(r.id.tv_15); tv10=(textview)findviewbyid(r.id.tv_10); tv5=(textview)findviewbyid(r.id.tv_5); tv2=(textview)findviewbyid(r.id.tv_2); } @override public void initlistener() { // todo auto-generated method stub clear.setonclicklistener(this); tv30.setonclicklistener(this); tv25.setonclicklistener(this); tv20.setonclicklistener(this); tv15.setonclicklistener(this); tv10.setonclicklistener(this); tv5.setonclicklistener(this); tv2.setonclicklistener(this); } @override public void initdata() { // todo auto-generated method stub } @override public void onclick(view v) { // todo auto-generated method stub if(v==clear){ gameview.clear(); return; } if(v==tv30){ gameview.setstrokewidth(30f); return; } if(v==tv25){ gameview.setstrokewidth(25f); return; } if(v==tv20){ gameview.setstrokewidth(20f); return; } if(v==tv15){ gameview.setstrokewidth(15f); return; } if(v==tv10){ gameview.setstrokewidth(10f); return; } if(v==tv5){ gameview.setstrokewidth(5f); return; } if(v==tv2){ gameview.setstrokewidth(2f); return; } } }
五、效果
运行效果图如下
六、疑问
当线条变粗时,线条会出现如上图中不连续的问题。请问高手这个怎么处理呢?我猜测应该要运行算法,但还不知道怎么运行。
文章就为大家介绍到这,其实还有许多知识点小编也不是很清楚,希望大家可以进行补充扩展,共同进步。