Android画图demo

如何在图片上画画呢?这里写了一个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;
		}

	}

}

五、效果

运行效果图如下

六、疑问

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

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-21 14:33:31

Android画图demo的相关文章

android Junit demo

package com.sondon.dhjk.test; import com.sondon.dhjk.utils.LogUtil; import junit.framework.TestCase; public class Test extends TestCase { private static final String TAG = "Test"; /** * 构造函数 * @param name */ public Test(String name) { super(name

百度地图SDK for Android【Demo兴趣点搜索】

百度地图SDK为开发者提供了便捷的检索服务.今天我将为大家介绍Poi检索相关的内容. 首先,我们要构建一个最基本的地图应用,具体介绍请参考:百度地图SDK for Android[Demo地图展示] 在这个工程的基础之上我们做一定的修改. 第一步,修改布局文件,添加关键字输入框和用于执行搜索操作的按钮.代码如下: [html] view plaincopy <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/a

Android Service demo例子使用详解

Android Service demo例子使用详解\ 概述Service 是 Android 的四大组件之一,它主要的作用是后台执行操作,Activity 属于带有 UI 界面跟用户进行交互,而 Service 则没有 UI 界面,所有的操作都是基于后台运行完成.并且 Service 跟 Activity 一样也是可以由其它的应用程序调用启动的,而且就算用户切换了应用程序,Service 依旧保持运行.一个组件如果与 Service 进行了绑定( bind ),就可以跟 Service 进行数

openwebrtc 服务端和android客户端demo安装

本文的原文连接是: http://blog.csdn.net/freewebsys/article/details/46649667 转载请一定注明出处! 1,关于openwebrtc OpenWebRTC 是基于 Gstreamer 实现的开源的.跨平台的 WebRTC 客户端框架,支持 H.264 和 VP8.利用 OpenWebRTC,WebRTC就不再仅仅是纯粹浏览器技术了,你可以在NativeAPP中使用WebRTC,并且还可以与浏览器WebRTC互联互通. 2,安装服务端demo d

Android 画图之Matrix(二)

上一篇Android画图之 Matrix(一) 讲了一下 Matrix的原理和运算方法,涉及到高等数学,有点难以理解.还好 Android 里面提供了对Matrix操作的一系 列方便的接口. Matrix的操作,总共分为 translate(平移),rotate(旋转),scale(缩放)和skew(倾斜)四种,每一种变换在 Android的API里都提供了 set, post和pre 三种操作方式,除了translate,其他三种操作都可以指定中心点.          set是直接设置 Ma

Android画图系列(二)——自己定义View绘制基本图形

这个系列主要是介绍下Android自己定义View和Android画图机制.自己能力有限.假设在介绍过程中有什么错误.欢迎指正 前言 在上一篇Android画图系列(一)--自己定义View基础中我们了解自己定义View相关的基本知识.只是,这些东西依然还是理论,接下来我们就实际绘制一些东西 在本篇文章中,我们先了解下面Canvas,而且画一些主要的图形 Canvas简单介绍 Canvas我们能够称之为画布.能够在上面绘制各种东西.是安卓平台2D图形绘制的基础.非常强大. 一般来说,比較基础的东

【百度AR】【Android】demo工程使用手记

[百度AR][Android]demo工程使用手记 demo工程获取和注意事项 百度AR平台地址:https://ar.baidu.com/testapply 技术文档地址:https://ai.baidu.com/docs#/DuMixAR-Android-SDK/top AR内容管理地址:https://dumix.baidu.com/content SDK下载地址:https://ai.baidu.com/sdk#ar 注意:先注册百度账号,选择免费试用即可 Demo工程的运行配置 注意:

神目人脸识别Android SDK Demo说明

神目人脸识别Android SDK Demo说明1.Demo使用说明SDK Demo主界面如图1-1所示,主要功能有:1:1,1:N,人脸库管理,设置选项四大功能.具体说明如下:(1)1:1,即图片1与图片2进行人脸比对,得出两者的相似度分数.界面如图1-2所示,点击空白处的图片,进入图片选择界面,选择需要比对的人脸图片即可.注意:图片保持正向,建议尺寸低于1920 X 1080,人脸清晰.(2)1:N,使用该功能之前请至人脸库管理中进行人脸注册.注册完成以后,进入1:N,如图1-3所示,图中显

android经典Demo(转载)

一篇不错的资源博文,转载分享给大家: 1.Android团队提供的示例项目  如果不是从学习Android SDK中提供的那些样例代码开始,可能没有更好的方法来掌握在Android这个框架上开发.由Android的核心开发团队提供了15个优秀的示例项目,包含了游戏.图像处理.时间显示.开始菜单快捷方式等.  地址: http://www.apkbus.com/android-13506-1-1.html 2. Remote Droid  RemoteDroid是一个Android应用,能够让用户