Android编程实现在Bitmap上涂鸦效果

本文实例讲述了Android编程实现在Bitmap上涂鸦效果。分享给大家供大家参考,具体如下:

布局文件:

<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
 android:layout_width="fill_parent"
 android:layout_height="fill_parent"
 android:orientation="vertical" >
 <LinearLayout
  android:id="@+id/handwriteview"
  android:layout_width="wrap_content"
  android:layout_height="wrap_content" />
 <LinearLayout
  android:layout_width="fill_parent"
  android:layout_height="fill_parent"
  android:orientation="horizontal"
  android:gravity="center_horizontal" >
  <Button
   android:id="@+id/clear"
   android:layout_width="200dp"
   android:layout_height="wrap_content"
   android:text="清屏" />
 </LinearLayout>
</LinearLayout>

重写的View文件:

public class HandWrite extends View
{
 private Paint paint = null;
 private Bitmap originalBitmap = null;
 private Bitmap new1Bitmap = null;
 private Bitmap new2Bitmap = null;
 private float clickX = 0,clickY = 0;
 private float startX = 0,startY = 0;
 private boolean isMove = true;
 private boolean isClear = false;
 private int color = Color.GREEN;
 private float strokeWidth = 2.0f;
 public HandWrite(Context context,Bitmap b)
 {
  super(context);
  originalBitmap = Bitmap.createBitmap(b).copy(Bitmap.Config.ARGB_8888, true);
  new1Bitmap = Bitmap.createBitmap(originalBitmap);
 }
 public void clear(){
  isClear = true;
  new2Bitmap = Bitmap.createBitmap(originalBitmap);
  invalidate();
 }
 public void setstyle(float strokeWidth){
  this.strokeWidth = strokeWidth;
 }
 @Override
 protected void onDraw(Canvas canvas)
 {
  super.onDraw(canvas);
  canvas.drawBitmap(HandWriting(new1Bitmap), 0, 0,null);
 }
 public Bitmap HandWriting(Bitmap originalBitmap)
 {
  Canvas canvas = null;
  if(isClear){
   canvas = new Canvas(new2Bitmap);
  }
  else{
   canvas = new Canvas(originalBitmap);
  }
  paint = new Paint();
  paint.setStyle(Style.STROKE);
  paint.setAntiAlias(true);
  paint.setColor(color);
  paint.setStrokeWidth(strokeWidth);
  if(isMove){
   canvas.drawLine(startX, startY, clickX, clickY, paint);
  }
  startX = clickX;
  startY = clickY;
  if(isClear){
   return new2Bitmap;
  }
  return originalBitmap;
 }
 @Override
 public boolean onTouchEvent(MotionEvent event)
 {
  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);
 }
}

Activity文件:

public class HandWritingActivity extends Activity
{
 /** Called when the activity is first created. */
 private LinearLayout handWrite = null;
 private Button clear = null;
 int requestWidth=116;
 int requestHeight=173;
 int inSampleSize;
 @Override
 public void onCreate(Bundle savedInstanceState)
 {
  super.onCreate(savedInstanceState);
  setContentView(R.layout.activity_hand_writing);
  handWrite = (LinearLayout)findViewById(R.id.handwriteview);
  clear = (Button)findViewById(R.id.clear);
  clear.setOnClickListener(new clearListener());
 }
 private class clearListener implements OnClickListener{
  public void onClick(View v)
  {
//   handWrite.clear();
   BitmapFactory.Options opts = new Options();
   opts.inJustDecodeBounds = true;// 让 bimapfactory假的解析这个位图,只获取位图的边框信息
   BitmapFactory.decodeResource(getResources(), R.drawable.cool, opts);
   if (opts.outHeight > requestHeight || opts.outWidth > requestWidth) {
    if (opts.outWidth > opts.outHeight) {
     inSampleSize = Math.round((float) opts.outHeight
       / (float) requestHeight);
    } else {
     inSampleSize = Math.round((float) opts.outWidth
       / (float) requestWidth);
    }
   }
    System.out.println("宽度:" + opts.outWidth);
    System.out.println("高度:" + opts.outHeight);
   opts.inSampleSize = inSampleSize;
   System.out.println(inSampleSize);
   opts.inJustDecodeBounds = false;// 由于已经得到了缩放比例 ,让位图工厂真正的解析这个位图
   // 由于前面 我们已经解析了这个输入流, 需要重新初始化这个输入流
   Bitmap b = BitmapFactory.decodeResource(getResources(), R.drawable.cool, opts);
   HandWrite hw = new HandWrite(HandWritingActivity.this, b);
   System.out.println(b.getWidth());
   handWrite.addView(hw);
  }
 }
}

整合的一个涂鸦工具类:

/**
 * 使用方法:
 * 1. 创建TuYaView类实例
 * 2. 调用drawTuya方法
 * 3. 参数1:context
 * 4. 参数2:图像的byte[]字节数组
 * 5. ImageView实例
 * 6. 画笔定义
 * **/
import com.ziipin.lhdc.utils.ToastUtil;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.graphics.BitmapFactory.Options;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;
public class TuYaView {
 // 原始图片
 private Bitmap mOrignBitmap;
 private Bitmap mEditBitmap;
 private int inSampleSize;
 private int requestWidth = 500;
 private int requestHeight = 700;
 /** 编辑图片的画布 */
 private Canvas mCanvas;
 private ImageView image;
 private Paint mPaint;
 public Bitmap drawTuya(Context context, byte[] _data, ImageView image,
   Paint mPaint) {
  this.image = image;
  this.mPaint = mPaint;
  mOrignBitmap = BitmapFactory.decodeByteArray(_data, 0, _data.length);
  return showEditBitmap(context, _data, image);
 }
 /**
  * 显示编辑的图片
  */
 private Bitmap showEditBitmap(Context context, byte[] _data, ImageView image) {
  mOrignBitmap = getScaleBitmap(_data, image);
  if (mOrignBitmap == null) {
   ToastUtil.show(context, "编辑出错");
  }
  mEditBitmap = mOrignBitmap.copy(mOrignBitmap.getConfig(), true);
  mCanvas = new Canvas(mEditBitmap);
  mCanvas.drawBitmap(mOrignBitmap, new Matrix(), new Paint());
  image.setImageBitmap(mEditBitmap);
  image.setOnTouchListener(mTouchListener);
  return mEditBitmap;
 }
 /**
  * 获取结果缩放放后的图片
  *
  * @return
  */
 private Bitmap getScaleBitmap(byte[] _data, ImageView image) {
  BitmapFactory.Options opts = new Options();
  opts.inJustDecodeBounds = true;// 让 bimapfactory假的解析这个位图,只获取位图的边框信息
  BitmapFactory.decodeByteArray(_data, 0, _data.length, opts);
  if (opts.outHeight > requestHeight || opts.outWidth > requestWidth) {
   if (opts.outWidth > opts.outHeight) {
    inSampleSize = Math.round((float) opts.outHeight
      / (float) requestHeight);
   } else {
    inSampleSize = Math.round((float) opts.outWidth
      / (float) requestWidth);
   }
  }
  opts.inSampleSize = inSampleSize;
  opts.inJustDecodeBounds = false;// 由于已经得到了缩放比例 ,让位图工厂真正的解析这个位图
  // 由于前面 我们已经解析了这个输入流, 需要重新初始化这个输入流
  Bitmap bmp = BitmapFactory
    .decodeByteArray(_data, 0, _data.length, opts);
  return bmp;
 }
 // touch事件
 private OnTouchListener mTouchListener = new OnTouchListener() {
  int startx = 0;
  int starty = 0;
  @Override
  public boolean onTouch(View v, MotionEvent event) {
   switch (event.getAction()) {
   case MotionEvent.ACTION_DOWN:// 手指第一次触摸屏幕
    startx = (int) event.getX();
    starty = (int) event.getY();
    break;
   case MotionEvent.ACTION_MOVE: // 手指在imageview上中移动
    int x = (int) event.getX();
    int y = (int) event.getY();
    mCanvas.drawLine(startx, starty, x, y, mPaint);
    startx = (int) event.getX();
    starty = (int) event.getY();
    image.invalidate();
    break;
   }
   return true;
  }
 };
}

希望本文所述对大家Android程序设计有所帮助。

(0)

相关推荐

  • Android 开发实例简单涂鸦板

    在Android上开发一些小应用既可以积累知识又可以增加乐趣,与任务式开发不同,所以想到在Android系统上实现一个简单的涂鸦板,这是我们练手的一种好的方法.   涂鸦板应用的代码实现 新建工程MyWall,修改/res/layout/main.xml文件,在里面添加一个SurfaceView和两个Button,用到了RelativeLayout布局,完整的main.xml文件如下: XML/HTML代码 <?xml version="1.0" encoding="u

  • Android编程开发之在Canvas中利用Path绘制基本图形(圆形,矩形,椭圆,三角形等)

    本文实例讲述了Android编程开发之在Canvas中利用Path绘制基本图形的方法.分享给大家供大家参考,具体如下: 在Android中绘制基本的集合图形,本程序就是自定义一个View组件,程序重写该View组件的onDraw(Canvase)方法,然后在该Canvas上绘制大量的基本的集合图形. 直接上代码: 1.自定义的View组件代码: package com.infy.configuration; import android.content.Context; import andro

  • Android通过Path实现搜索按钮和时钟复杂效果

    在Android中复杂的图形的绘制绝大多数是通过path来实现,比如绘制一条曲线,然后让一个物体随着这个曲线运动,比如搜索按钮,比如一个简单时钟的实现: 那么什么是path呢! 定义:path  就是路径,就是图形的路径的集合,它里边包含了路径里边的坐标点,等等的属性.我们可以获取到任意点的坐标,正切值. 那么要获取Path上边所有点的坐标还需要用到一个类,PathMeasure; PathMesure: PathMeasure是一个用来测量Path的类,主要有以下方法: 构造方法 公共方法 可

  • Android高手进阶教程(二十六)之---Android超仿Path菜单的功能实现!

    Hi~大家好,出来创业快3个月了,一切还不错,前一段时间用了业余时间搞了个问答类网站YQMA.想做中国的stackoverflow,哈哈,只是YY下,希望大家多多支持! 好了,今天给大家分享的是Path菜单的简单实现,可以支持自定义方向(左上,右上,右下,左下),并且可以自定义菜单的个数,难点就是菜单的摆放位置(动态设置margin),还有动画的实现,其实动画只是简单用了个TranslateAnimation,N个菜单一起移动的时候感觉很cool~ 这里也用到了自定义标签,这里不懂的童鞋可以看我

  • Android Path绘制贝塞尔曲线实现QQ拖拽泡泡

    这两天学习了使用Path绘制贝塞尔曲线相关,然后自己动手做了一个类似QQ未读消息可拖拽的小气泡,效果图如下: 最终效果图 接下来一步一步的实现整个过程. 基本原理 其实就是使用Path绘制三点的二次方贝塞尔曲线来完成那个妖娆的曲线的.然后根据触摸点不断绘制对应的圆形,根据距离的改变改变原始固定圆形的半径大小.最后就是松手后返回或者爆裂的实现. Path介绍: 顾名思义,就是一个路径的意思,Path里面有很多的方法,本次设计主要用到的相关方法有 moveTo() 移动Path到一个指定的点 qua

  • Android自定义View系列之Path绘制仿支付宝支付成功动画

    前言 使用支付宝付款时,我们可以看到成功或者失败都会有个动画提示,如果我们需要做这样的效果的话,当然,你可以让设计师给你做个GIF,但是我们知道图像比较耗内存的,我们自己可以用代码实现还是代码实现好点吧. 效果 实现方法 首先我们需要了解PathMeasure这个类,这个类我们可以理解为用来管理Path.我们主要看几个方法. PathMeasure(): 构造方法 ,实例化一个对象 PathMeasure(Path path,boolean isClosed):传入Path对象和是否闭合,pat

  • Android 使用Path实现涂鸦功能

    今天实现一个涂鸦效果,会分几步实现,这里有一个重要的知识点就是图层,要理解这个,不然你看这篇博客,很迷茫,迷茫的苍茫的天涯是我的爱,先从简单的需求做起,绘制一条线,代码如下: package com.tuya; import android.content.Context; import android.graphics.Canvas; import android.graphics.Paint; import android.graphics.Path; import android.util

  • Android编程实现在Bitmap上涂鸦效果

    本文实例讲述了Android编程实现在Bitmap上涂鸦效果.分享给大家供大家参考,具体如下: 布局文件: <?xml version="1.0" encoding="utf-8"?> <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="fill_parent" andro

  • Android编程实现的手写板和涂鸦功能

    本文实例讲述了Android编程实现的手写板和涂鸦功能.分享给大家供大家参考,具体如下: 下面仿一个Android手写板和涂鸦的功能,直接上代码: write_pad.xml <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:greendroid="http://schemas.android.com/apk/res/com.cyrilmottier.androi

  • android中实现在ImageView上随意画线涂鸦的方法

    我实现的思路: 1.继承ImageView类 2.重写onTouchEvent方法,在ACTION_MOVE(即移动时),记录下所经过的点坐标,在ACTION_UP时(即手指离开时,这时一条线已经画完),将所画的线(点的集合)保存在一个集合中 3.重写onDraw方法,利用canvas和所记录下的线和点画出线来 可能我讲的十分笼统,下面来看看实际的代码吧 //代表ImageView上的一点 public class ViewPoint { float x; float y; } //表示一条线

  • Android编程实现图片的上传和下载功能示例

    本文实例讲述了Android编程实现图片的上传和下载功能.分享给大家供大家参考,具体如下: 在实现一个Android的WEB服务客户端,比如微博,论坛客户端时,经常会使用到图片的上传和下载.在这里介绍如何利用HttpClient实现图片的上传和下载功能. 1 图片上传:上传图片时,首先获得图片的路径,创建文件,并将图片转化为字节流写入到request,并发送该请求. 客户端代码: File file = new File(imageUrl); String httpUrl = httpDomai

  • Android编程设定activity进入和退出效果的方法

    本文实例讲述了Android编程设定activity进入和退出效果的方法.分享给大家供大家参考,具体如下: 看了android的源代码和资源文件,终于明白如何去修改设置Dialog和Activity的进入和退出效果了.设置Dialog首先通过getWindow()方法获取它的窗口,然后通过getAttributes()方法获得window的WindowManager.LayoutParams lp, lp有个公共属性windowAnimations, 只要把要实现的animation的id赋值给

  • Android编程实现小说阅读器滑动效果的方法

    本文实例讲述了Android编程实现小说阅读器滑动效果的方法.分享给大家供大家参考,具体如下: 看过小说都知道小说阅读器翻页有好多种效果,比如仿真翻页,滑动翻页,等等.由于某种原因,突然想写一个简单点的滑动翻页效果.在这里写出来也没有什么意图,希望大家可以根据这个效果举一反三,写出其他的效果.图就不上了. 下面是代码:大家理解onTouch事件即可 package com.example.testscroll.view; import android.content.Context; impor

  • Android编程之界面跳动提示动画效果实现方法

    本文实例讲述了Android编程之界面跳动提示动画效果实现方法.分享给大家供大家参考,具体如下: 上一个效果图: 先上布局: <RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android" xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent" a

  • Android编程简单获取网络上的图片

    本文实例讲述了Android编程简单获取网络上的图片的方法.分享给大家供大家参考,具体如下: 要获取网络上的图片,首先得有网络的访问权限,这个不再写了,以前的文章中写过,还有布局方式不再写了,就是写也是一个简单的布局,没有多大意义,直接上核心代码: 这是本人使用的一个简单的类,来获取网上的图片. public static Bitmap getImage(String Url) throws Exception { try { URL url = new URL(Url); String res

  • Android编程基于自定义view实现公章效果示例【附源码下载】

    本文实例讲述了Android编程基于自定义view实现公章效果.分享给大家供大家参考,具体如下: 上次去一个公司面试,面试官问了一个题,怎么用android的自定义view实现一个公章的效果,据说这是华为之前的面试题,我想了下,要是公章的效果,最外层是一个圆,里面是一个五角星,但是这文字怎么画呢,比较难搞,后来回来看了下java的api,发现人家的Path里面本来就提供了这么一个方法: public void addArc(RectF oval, float startAngle, float

  • Android编程实现基于BitMap获得图片像素数据的方法

    本文实例讲述了Android编程实现基于BitMap获得图片像素数据的方法.分享给大家供大家参考,具体如下: 网上看到的参考是: int[] pixels = new int[bit.getWidth()*bit.getHeight()];//保存所有的像素的数组,图片宽×高 bit.getPixels(pixels,0,bit.getWidth(),0,0,bit.getWidth(),bit.getHeight()); for(int i = 0; i < pixels.length; i+

随机推荐