Welcome 微信登录

首页 / 移动开发 / Android / Android简单实现画图功能

如何在图片上画画呢?这里写了一个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 stuboriginalBitmap = 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" ><LinearLayoutandroid:layout_width="match_parent" android:layout_height="50dp"android:orientation="horizontal"> <LinearLayoutandroid:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextViewandroid:id="@+id/tv_30" android:layout_width="30dp" android:layout_height="30dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayoutandroid:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextViewandroid:id="@+id/tv_25" android:layout_width="25dp" android:layout_height="25dp" android:background="@drawable/bg_notifaction" /> </LinearLayout><LinearLayoutandroid:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextViewandroid:id="@+id/tv_20" android:layout_width="20dp" android:layout_height="20dp" android:background="@drawable/bg_notifaction" /> </LinearLayout><LinearLayoutandroid:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextViewandroid:id="@+id/tv_15" android:layout_width="15dp" android:layout_height="15dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayoutandroid:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextViewandroid:id="@+id/tv_10" android:layout_width="10dp" android:layout_height="10dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayoutandroid:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextViewandroid:id="@+id/tv_5" android:layout_width="5dp" android:layout_height="5dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> <LinearLayoutandroid:layout_width="0dp" android:layout_height="match_parent" android:layout_weight="1" android:gravity="center" > <TextViewandroid:id="@+id/tv_2" android:layout_width="2dp" android:layout_height="2dp" android:background="@drawable/bg_notifaction" /> </LinearLayout> </LinearLayout><picturegame.view.GameViewandroid:layout_width="match_parent" android:layout_height="300dp" android:id="@+id/gameview" /><Buttonandroid: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; }} } 
五、效果
运行效果图如下


六、疑问
当线条变粗时,线条会出现如上图中不连续的问题。请问高手这个怎么处理呢?我猜测应该要运行算法,但还不知道怎么运行。
文章就为大家介绍到这,其实还有许多知识点小编也不是很清楚,希望大家可以进行补充扩展,共同进步。