Android常用的绘图类有Bitmap类、BitmapFactory类、Canvas类、Paint类,下面分别做简单的总结

Bitmap类即位图类,主要方法有以下几个

createBitmap(int width, int height, Bitmap.Config config)----创建指定宽度、高度的位图
compress(Bitmap.CompressFormat format, int quality, OutputStream stream)----保存位图,用于把位图写出到一个OutputStream

BitmapFactory类即位图工厂,主要用于从不同的数据源来解析、创建Bitmap对象。主要方法有

decodeFile(String pathName)----从指定文件中解析、创建`Bitmap`对象。传入图片路径的字符串
decodeResource(Resources res, int id)----根据给定的资源id,从指定资源解析、创建`Bitmap`对象
decodeStream(InputStream is)----从指定的输入流中解析、创建`Bitmap`对象

Paint类即花壁类。用来描述图形的颜色、线宽、透明度、填充效果等信息。使用时首先要创建Paint对象。通过对象来调用相应方法设置上述信息。主要有以下方法

Paint()----Create a new paint with default settings.构造器,用来创建一个paint对象 ,使用默认属性
Paint(int flags)----Create a new paint with the specified flags.构造器,用来创建一个paint对象 ,使用指定flags属性
setColor(int color)----Set the paint's color.设置颜色
setAlpha(int a)---- that only assigns the color's alpha value, leaving its r,g,b values unchanged.设置透明度
setDither(boolean dither)----辅助设定是否使用图片抖动处理
setAntiAlias(boolean aa)----设置是否使用抗锯齿功能
setShadowLayer(float radius, float dx, float dy, int shadowColor)----设置阴影参数,radius表示阴影角度,dx、dy、shadowColor分别表示阴影的位置坐标以及颜色参数
setTextAlign(Paint.Align align)----设置绘制文本时的文字对齐方式
setTextSize(float textSize)----设置绘制文本时的文字大小
setFakeBoldText(boolean fakeBoldText)----设置绘制文字时是否为粗体文字
setXfermode(Xfermode xfermode)----设置图形重叠时的处理方式,比如合并、取交集或并集,经常用来制作橡皮的擦除效果

Canvas类代表画布,通过该类提供的方法可以绘制出各种图形,比如圆形、矩形、线条等。在Android中绘图首先要创建一个继承自View的视图,然后重写其onDraw()方法,然后再Activity中添加该视图。下面来看Canvas类中的主要方法如下

Canvas()----构造器,创建一个空的Canvas对象
Canvas(Bitmap bitmap)----Construct a canvas with the specified bitmap to draw into.构造器,创建一个Canvas对象,接收一个位图对象作为参数,在该位图对象上绘图
drawRect(RectF rect, Paint paint)----使用画笔画出指定矩形
drawRect(RectF rect, Paint paint)----使用画笔画出指定椭圆形
drawCircle(float cx, float cy, float radius, Paint paint)----使用画笔在指定位置cx、cy画指定半径radius的圆形
drawLine(float startX, float startY, float stopX, float stopY, Paint paint)----使用画笔画出指定起点startX、startY和指定终点stopX、stopY的直线

值得特别说明的是创建Canvas对象的时候需要传入三个参数,其中第二个参数需要接收一个Matrix对象即矩阵对象,Android中对图片的处理都是通过矩阵来实现的,其实很多专业的图片、图像处理软件例如pspr等也都是通过矩阵来实现对像素的处理。那么我们就可以通过创建一个矩阵对象来调用其相应方法来实现对图片的平移、缩放、旋转这三种基本的特效处理,然后在中和三种处理的基础上实现镜面效果、湖面倒影效果等。具体通过下面代码来看

首先来看布局文件,定义可一个按钮加载效果图片,和两个ImageView用来显示处理前后的图片,形成对比。

<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="vertical" >

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="@string/load_picture" 
        android:onClick="loadPicture"
        />

    <ImageView 
        android:id="@+id/iv_src"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

    <ImageView 
        android:id="@+id/iv_copy"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</LinearLayout>

再来看MainActivity代码如下,其实Android中处理图片的步骤也就分五步,在下面的代码中我都通过序号来标出方便查看

package com.example.picturehandle;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.View;
import android.widget.ImageView;

public class MainActivity extends Activity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

    }

    public void loadPicture(View v) {

        // 通过指定资源ID加载图片。加载原图
        Bitmap bmSrc = BitmapFactory.decodeResource(getResources(), R.drawable.new_manhua);

        // 1.创建原图的副本.与原图宽高一样
        Bitmap bmCopy = Bitmap.createBitmap(bmSrc.getWidth(), bmSrc.getHeight(), bmSrc.getConfig());
        // 2.创建画笔
        Paint paint = new Paint();
        // 3.创建画布
        Canvas canvas = new Canvas(bmCopy);
        // 4.开始作画。特效处理
        // 4.1创建一个矩阵对象
        Matrix mt = new Matrix();
//      // 4.1.1旋转效果
//      mt.setRotate(45, bmCopy.getWidth() / 2, bmCopy.getHeight() / 2);
//      // 4.1.2平移效果
//      mt.setTranslate(30, 60);
//      // 4.1.3缩放效果
//      mt.setScale(0.8f, 1.5f);
//      // 4.1.4镜像效果。通过缩放、平移
//      mt.setScale(-1, 1);     // 缩放水平值设为-1,竖直值设为1
//      mt.postTranslate(bmCopy.getWidth(), 0);     // 向右平移图片宽度个像素
        // 4.1.5倒影效果。通过缩放、平移
        mt.setScale(1, -1);
        mt.postTranslate(0, bmCopy.getHeight());

        // 4.2把设置好的矩阵传入画布
        canvas.drawBitmap(bmSrc, mt, paint);

        // 5.1显示原图
        ImageView iv_src = (ImageView) findViewById(R.id.iv_src);
        iv_src.setImageBitmap(bmSrc);
        // 5.2显示副本
        ImageView iv_copy = (ImageView) findViewById(R.id.iv_copy);
        iv_copy.setImageBitmap(bmCopy);
    }
}

最后贴一个TearClothes的简单应用。先说一下实现的原理,上下两张图片重叠在一起显示,所以在未处理之前我们只看得到上层的图片,我们通过设置触摸监听事件,当手指滑动时将滑动的轨迹设置为透明,这样就可以实现擦除效果。其实早在10年Android刚刚普及的时候,市场就有很多应用用的是这个原理实现的,比如撕衣服、刮刮乐等应用。下面看代码

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}"
    android:orientation="vertical" >

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:src="@drawable/after"
        />
    <ImageView
        android:id="@+id/cover"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        />

</RelativeLayout>

MainActivity代码如下

package com.example.tearclothes;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.Paint;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.view.View.OnTouchListener;
import android.widget.ImageView;

public class MainActivity extends Activity {

private ImageView pre;

private Bitmap prec;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);

//      // 加载底层图片
//      Bitmap biUnder = BitmapFactory.decodeResource(getResources(), R.drawable.after);
//      // 拿到ImageView实例
//      ImageView after = (ImageView) findViewById(R.drawable.after);
//      after.setImageBitmap(biUnder);

    // 加载上层图片
    Bitmap biUp = BitmapFactory.decodeResource(getResources(), R.drawable.pre);
    // 拿到ImageView实例
    pre = (ImageView) findViewById(R.id.cover);
    // 显示上层图片
    pre.setImageBitmap(biUp);
    // 拿到上层图片副本
    prec = Bitmap.createBitmap(biUp.getWidth(), biUp.getHeight(), biUp.getConfig());
    // 画笔
    Paint paint = new Paint();
    // 画布
    Canvas canvas = new Canvas(prec);
    // 作画
    canvas.drawBitmap(biUp, new Matrix(), paint);
    pre.setOnTouchListener(new OnTouchListener() {

        @Override
        public boolean onTouch(View v, MotionEvent event) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_MOVE:
                int x = (int) event.getX();
                int y = (int) event.getY();
                for (int i = -5; i < 5; i++) {
                    for (int j = -5; j < 5; j++) {
                        // 把透明区域设置为圆形
                        if (Math.sqrt(i*i + j*j) <= 10)
                        // 把捕捉到的坐标对应的像素设置为透明
                        prec.setPixel(x + i, y + j, Color.TRANSPARENT);
                    }
                }
                pre.setImageBitmap(prec);
                break;
            default:
                break;
            }
            return true;
        }
    });



    }
}