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 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;
    } 

  } 

} 

五、效果
运行效果图如下

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

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

(0)

相关推荐

  • Android画图并保存图片的具体实现代码

    Canvas是一个画布,你可以建立一个空白的画布,就直接new一个Canvas对象,不需要参数.也可以先使用BitmapFactory创建一个Bitmap对象,作为新的Canvas对象的参数,也就是说这个画布不是空白的,如果你想保存图片的话,最好是Bitmap是一个新的,而不是从某个文件中读入进来的,或者是Drawable对象. 然后使用Canvas画第一张图上去,在画第二张图上去,最后使用Canvas.save(int flag)的方法进行保存,注意save方法里面的参数可以保存单个图层,如果

  • Android入门之画图详解

    前文常用的控件介绍了不少,现在就来讨论一下手机开发中常用到的画图.要掌握Android的画图,首先就要了解一下,基本用到的如下一些图形接口: 1.Bitmap,可以来自资源/文件,也可以在程序中创建,实际上的功能相当于图片的存储空间: 2.Canvas,紧密与Bitmap联系,把Bitmap比喻内容的话,那么Canvas就是提供了众多方法操作Bitamp的平台: 3.Paint,与Canvas紧密联系,是"画板"上的笔刷工具,也用于设置View控件上的样式: 4.Drawable,如果

  • Android编程画图之抗锯齿解决方法

    本文实例分析了Android编程画图之抗锯齿解决方法.分享给大家供大家参考,具体如下: 在画图的时候,图片如果旋转或缩放之后,总是会出现那些华丽的锯齿.其实Android自带了解决方式. 方法一:给Paint加上抗锯齿标志.然后将Paint对象作为参数传给canvas的绘制方法. 复制代码 代码如下: paint.setAntiAlias(true); 方法二:给Canvas加上抗锯齿标志. 有些地方不能用paint的,就直接给canvas加抗锯齿,更方便. 复制代码 代码如下: canvas.

  • Android简单实现画图功能

    如何在图片上画画呢?这里写了一个demo,供大家参考 一.先看一眼工程结构 工程结构: 二.自定义view 这个自定义view实现了保留轨迹的功能,代码如下 package picturegame.view; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import and

  • Android 简单实现倒计时功能

    在 Android 中倒计时功能是比较常用的一个功能,比如短信验证码,付款倒计时等.实现方式有Handler.Thread 等,但是实现起来都有点麻烦,其实Android已经为我们封装好了一个抽象类 CountDownTimer,可以简单的实现倒计时功能,如下图所示. CountDownTimer 实现倒计时功能的机制也是用Handler 消息控制,只是它帮我们已经封装好了,先看一下它的介绍. Schedule a countdown until a time in the future, wi

  • Android简单实现计算器功能

    本文实例为大家分享了Android简单实现计算器的具体代码,供大家参考,具体内容如下 一.UI布局及代码 页面效果 布局代码 <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"     android:layout_width="match_pare

  • Android基于广播事件机制实现简单定时提醒功能代码

    本文实例讲述了Android基于广播事件机制实现简单定时提醒功能代码.分享给大家供大家参考,具体如下: 1.Android广播事件机制 Android的广播事件处理类似于普通的事件处理.不同之处在于,后者是靠点击按钮这样的组件行为来触发,而前者是通过构建Intent对象,使用sentBroadcast()方法来发起一个系统级别的事件广播来传递信息.广播事件的接收是通过定义一个继承Broadcast Receiver的类实现的,继承该类后覆盖其onReceive()方法,在该方法中响应事件.And

  • 超简单的几行代码搞定Android底部导航栏功能

    超简单,几行代码搞定Android底部导航栏-–应项目需求以及小伙伴的留言,新加了两个方法: 设置底部导航栏背景图片 添加底部导航栏选项卡切换监听事件 底部导航栏的实现也不难,就是下边是几个Tab切换,上边一般是一个FrameLayout,然后FrameLayout中切换fragment. 网上有不少关于Android底部导航栏的文章,不过好像都只是关于下边Tab切的,没有实现Tab与fragment的联动,用的时候还要自己手写这部分代码,对我这个比较懒(据说,懒是程序员的一种美德_#)得程序员

  • Android 简单封装获取验证码倒计时功能

    效果如下图所示: 如图所示的效果相信大家都不陌生,我们可以使用很多种方法去实现此效果,这里自己采用 CountDownTimer 定时器简单封装下此效果,方便我们随时调用. 首页先在 attrs.xml 中定义下所需的几个属性: <resources> <declare-styleable name="CountDownButton"> <attr name="millisinfuture" format="integer&q

  • Android自定义View实现简单文字描边功能

    本文实例为大家分享了Android实现简单文字描边功能的具体代码,供大家参考,具体内容如下 效果图: 实现代码: package com.example.zhangyu.myview.widget; import android.content.Context; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import android.graphics.Canvas; import android.

  • Android简单的短信验证功能的实现代码

    相信有很多朋友在做三方登陆的时候会加入短信验证的功能,最近刚好被分配安排实现这一需求,本人新手一枚,特地去网上搜了资料,目前用的比较多的大汉.云通讯还有MOB的smssdk,对比之下,最终选择了完全免费的MOB产品试试手,下面就是我在使用sdk过程中一些心得,希望看到的大神给点建议,喜欢的给个小心心就好. 首先我上网百度了下Mob的官网(http://www.mob.com/)作为第一次使用习惯性的先打开文档介绍,关于使用方法这里介绍的算是比较详细的,我这里也不做赘述了,整个文档浏览了一遍,介绍

  • Android编程实现简单文件浏览器功能

    本文实例讲述了Android编程实现简单文件浏览器功能.分享给大家供大家参考,具体如下: 运行效果: 布局: <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" android:lay

  • Android 简单的实现滑块拼图验证码功能

    实现滑块拼图验证码功能之前已经写过一篇了,上一篇使用的是自定义控件的方式实现这个功能,主要还是想让童鞋们知其然更知其所以然,还没看的童鞋可以先看看Android实现滑块拼图验证码功能这篇. 在项目的开发过程中,时间比较紧急,通过自定义的方式很显然需要耗费很多时间去写,所以我们需要使用更简单的方式实现,这样会帮我们节省很多时间去解决其它的问题,使用依赖库的方式显然是最节省时间的,下面我们来看看是怎么实现的吧! 本篇主要从两方面进行介绍: 1.使用依赖库实现最终的功能: 2.依赖库的介绍: 实现过程

随机推荐