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 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
画图
java 实现画图功能、画图可以实现的功能、bbs功能实现简单描述、jsp实现简单登录功能、android搜索功能实现,以便于您获取更多的相关知识。

时间: 2024-10-21 16:37:53

Android简单实现画图功能_Android的相关文章

Android简单音乐播放实例_Android

Service翻译成中文是服务,熟悉Windows 系统的同学一定很熟悉了.Android里的Service跟Windows里的Service功能差不多,就是一个不可见的进程在后台执行. Android中的服务,它与Activity不同,它是不能与用户交互的,不能自己启动的,运行在后台的程序,如果我们退出应用时,Service进程并没有结束,它仍然在后台运行,例如我们打开一个音乐播放器来听音乐,在听音乐的同时也想做下其它的事情,比如上网聊Q.或者上网浏览新闻之类的事情.这样的话,我们就需要用到S

Android仿外卖购物车功能_Android

先看看效果图: 知识点分析 效果图来看不复杂内容并没多少,值得介绍一下的知识点也就下面几个吧 - 列表标题悬停 - 左右列表滑动时联动 - 添加商品时的抛物线动画 - 底部弹出购物车清单 - 数据的同步 另外就是实现效果的时候可能会遇到的几个坑... 布局很简单直接进入代码 1:列表标题悬停 现在做项目列表什么的基本抛弃了ListView改用RecyclerView,上篇博客中的标题悬停也是使用了一个RecyclerView的开源项目sticky-headers-recyclerview,不过写

Android Camera开发手电筒功能_Android

这是一个简单的运用Android Camera开发手电筒功能,AndroidManifest.xml文件的入口是startapp,这个文件没上传上来,大家可以自己写. flashlight.java package com.android.app; import android.app.Activity; import android.hardware.Camera; import android.hardware.Camera.Parameters; import android.os.Bun

Android实现微信支付功能_Android

开发Android APP微信支付功能,需要完成三个步骤:第一步生成预支付订单.第二步生成微信支付参数.第三步调起微信APP支付.除了需要审核通过的APP应用外,还需要获得微信支付接口权限,然后获取对应的商户号.API密钥,这两者缺一不可,并且在APP微信支付中使用 获得商户号.API密钥 在微信开放平台中查看审核通过的APP应用,是否申请支付功能,若已申请,登录微信支付|商户平台:http://pay.weixin.qq.com 查看对应的商户号.API密钥 >申请微信支付接口 >登录商户平

Android实现返回键功能_Android

记录用户点击的操作历史,使用栈数据结构,频繁的操作栈顶(添加,获取,删除),使用LinkedList 捕获用户的返回键操作,响应返回键,返回上一个界面 MainActivity.java /** * 返回键处理 */ @Override public boolean onKeyDown(int keyCode, KeyEvent event) { if(keyCode==KeyEvent.KEYCODE_BACK){ boolean result=MiddleManager.getInstanc

Android实现拍照截图功能_Android

本文将向大家展示如何拍照截图. 先看看效果图: 拍照截图有点儿特殊,要知道,现在的Android智能手机的摄像头都是几百万的像素,拍出来的图片都是非常大的.因此,我们不能像对待相册截图一样使用Bitmap小图,无论大图小图都统一使用Uri进行操作. 一.首先准备好需要使用到的Uri: private static final String IMAGE_FILE_LOCATION = "file:///sdcard/temp.jpg";//temp file Uri imageUri =

Android自定义控件实现简单写字板功能_Android

先来看看效果图 就是简单的根据手指写下的轨迹去画出内容 一.实现 之前一篇文章里提到了android官方给出的自定义控件需要考虑以下几点: 创建View 处理View的布局 绘制View 与用户进行交互 优化已定义的View 就按照这个步骤来完成今天的自定义控件 1.创建View上篇提到创建View这一步的时候要考虑的就是很简单的自定义属性的声明.使用. 今天的控件可以有一些什么自定义属性呢?要实现写字板,其实就是三个东西:写字板的颜色.笔的颜色.笔的粗细.所以接下来自定义属性. <?xml v

Android RecyclerView实现下拉列表功能_Android

现在市面上的很多的应用,都带有下拉列表的功能,将所有选项都放在下拉列表中,当用户点击选择的时候,弹出所有的选项,用户选择一项后,下拉列表自动隐藏,很多下拉列表都是用ListView + PopupWindow来实现的,由于Google推出了替代ListView的RecyclerView,所以简单实现一下: MainActivity.java package com.jackie.countdowntimer; import android.graphics.drawable.BitmapDraw

Android 微信图片分享功能_Android

我们都知道,通过 微信官方 分享sdk 支持图片分享,而且有多种方式.官方链接 可直接查看,不再赘述. 本文要解决的问题是,分享本地带二维码的图片给微信好友和朋友圈.朋友圈图片能够实现长按识别,给微信好友对话框的图片 在 iOS 可以正常识别,但是 Android 端却不能识别 ,为什么? 以下引用网友的回答: 经过分析和功能对比,android wechat app 中有两种图片浏览方式,图片预览,和图片本地发送后的打开查看(这个有识别动作)页面.预览图片功能中,不包含长按手势的识别功能,仔细