欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

Android简单实现画图功能

程序员文章站 2024-02-26 18:10:04
如何在图片上画画呢?这里写了一个demo,供大家参考 一、先看一眼工程结构 工程结构: 二、自定义view 这个自定义view实现了保留轨迹的功能,代码如下...

如何在图片上画画呢?这里写了一个demo,供大家参考
一、先看一眼工程结构
工程结构:

Android简单实现画图功能

二、自定义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; 
    } 
     
  } 
    
} 

五、效果
运行效果图如下

Android简单实现画图功能

六、疑问
当线条变粗时,线条会出现如上图中不连续的问题。请问高手这个怎么处理呢?我猜测应该要运行算法,但还不知道怎么运行。

文章就为大家介绍到这,其实还有许多知识点小编也不是很清楚,希望大家可以进行补充扩展,共同进步。