1.MainActivity类：

```package org.wp.activity;
import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.PorterDuffXfermode;
import android.graphics.Bitmap.Config;
import android.graphics.PorterDuff.Mode;
import android.graphics.Paint;
import android.graphics.drawable.BitmapDrawable;
import android.os.Bundle;
import android.widget.ImageView;
/**
* ==========================================
* Matrix
* ==========================================
* The Matrix class holds a 3x3 matrix for transforming coordinates.
* Matrix does not have a constructor,
* so it must be explicitly initialized using either reset()
* - to construct an identity matrix,
* or one of the set..() functions
* (e.g. setTranslate, setRotate, etc.).
*
* Matrix 中文里叫矩阵，高等数学里有介绍
* 在图像处理方面，主要是用于平面的缩放、平移、旋转等操作。
* Matrix的操作，总共分为translate(平移)，rotate(旋转)，
* scale(缩放)和skew(倾斜)四种，
* 每一种变换在Android的API里都提供了set, post和pre三种操作方式
* 除了translate，其他三种操作都可以指定中心点。
*
* ==========================================
* createBitmap
* ==========================================
* public static Bitmap createBitmap (Bitmap source, int x, int y,
*                  int width, int height, Matrix m, boolean filter)
* Since: API Level 1 Returns an immutable bitmap from subset of the
*        source bitmap, transformed by the optional matrix.
*        It is initialized with the same density as the original bitmap.
* Parameters
* source  The bitmap we are subsetting
* x  The x coordinate of the first pixel in source
* y  The y coordinate of the first pixel in source
* width  The number of pixels in each row
* height  The number of rows
* m  Optional matrix to be applied to the pixels
* filter  true if the source should be filtered.
*         Only applies if the matrix contains more than
*         just translation.
* Returns
* A bitmap that represents the specified subset of source
* Throws
* IllegalArgumentException
* if the x, y, width, height values are outside of the
* dimensions of the source bitmap.
*
* source 源 bitmap对象
* x 源坐标x位置
* y 源坐标y位置
* width 宽度
* height 高度
* m 接受的maxtrix对象，如果没有可以设置 为null
* filter 该参数仅对maxtrix包含了超过一个翻转才有效
*
* ==========================================
* ==========================================
* public LinearGradient (float x0, float y0, float x1, float y1, i
*              nt color0, int color1, Shader.TileMode tile)
* Since: API Level 1 Create a shader that draws a linear gradient along a line.
* Parameters
* x0  The x-coordinate for the start of the gradient line
* y0  The y-coordinate for the start of the gradient line
* x1  The x-coordinate for the end of the gradient line
* y1  The y-coordinate for the end of the gradient line
* color0  The color at the start of the gradient line.
* color1  The color at the end of the gradient line.
* tile  The Shader tiling mode
*
*
* 在android平台中提供了两种重载方式来实例化该类分别为，
* 他们的不同之处为参数中第一种方法可以用颜色数组，和位置来实现更细腻的过渡效果，
* 比如颜色采样int[] colors数组中存放20种颜色，则渐变将会逐一处理。
* 而第二种方法参数仅为起初颜色color0和最终颜色color1。
* LinearGradient(float x0, float y0, float x1, float y1,
*      int[] colors, float[] positions, Shader.TileMode tile)
* LinearGradient(float x0, float y0, float x1, float y1,
*      int color0, int color1, Shader.TileMode tile)
*
* 参数一为渐变起初点坐标x位置，参数二为y轴位置，
* 参数三和四分辨对应渐变终点，最后参数为平铺方式，这里设置为镜像
*
*
* ==========================================
* setXfermode
* ==========================================
* Xfermode
* 可以通过修改Paint的Xfermode来影响在
* Canvas已有的图像上面绘制新的颜色的方式 。
*
* 在正常的情况下，在已有的图像上绘图将会在其上面添加一层新的形状。
* 如果新的Paint是完全不透明的，那么它将完全遮挡住下面的Paint；
* 如果它是部分透明的，那么它将会被染上下面的颜色。
*
* 下面的Xfermode子类可以改变这种行为：
*
* AvoidXfermode  指定了一个颜色和容差，
*                    强制Paint避免在它上面绘图(或者只在它上面绘图)。
* PixelXorXfermode  当覆盖已有的颜色时，应用一个简单的像素XOR操作。
*
* PorterDuffXfermode  这是一个非常强大的转换模式，使用它，
*                     可以使用图像合成的16条Porter-Duff规则的任意
*                     一条来控制Paint如何与已有的Canvas图像进行交互。
*
* 16条Porter-Duff规则
* 1.PorterDuff.Mode.CLEAR
* 2.PorterDuff.Mode.SRC
* 3.PorterDuff.Mode.DST
* 4.PorterDuff.Mode.SRC_OVER
* 5.PorterDuff.Mode.DST_OVER
* 6.PorterDuff.Mode.SRC_IN
* 7.PorterDuff.Mode.DST_IN
* 8.PorterDuff.Mode.SRC_OUT
* 9.PorterDuff.Mode.DST_OUT
* 10.PorterDuff.Mode.SRC_ATOP
* 11.PorterDuff.Mode.DST_ATOP
* 12.PorterDuff.Mode.XOR
* 13.PorterDuff.Mode.DARKEN
* 14.PorterDuff.Mode.LIGHTEN
* 15.PorterDuff.Mode.MULTIPLY
* 16.PorterDuff.Mode.SCREEN
*
* @author wp
*/
public class MainActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
ImageView myImageView = (ImageView) this.findViewById(R.id.myImageView);
Bitmap bitmap = ((BitmapDrawable) getResources().getDrawable(
R.drawable.qianqian)).getBitmap();
myImageView.setImageBitmap(createReflectedImage(bitmap));
}
private Bitmap createReflectedImage(Bitmap originalBitmap) {
// 图片与倒影间隔距离
final int reflectionGap = 4;

// 图片的宽度
int width = originalBitmap.getWidth();
// 图片的高度
int height = originalBitmap.getHeight();

Matrix matrix = new Matrix();
// 图片缩放，x轴变为原来的1倍，y轴为-1倍,实现图片的反转
matrix.preScale(1, -1);
// 创建反转后的图片Bitmap对象，图片高是原图的一半。
Bitmap reflectionBitmap = Bitmap.createBitmap(originalBitmap, 0,
height / 2, width, height / 2, matrix, false);
// 创建标准的Bitmap对象，宽和原图一致，高是原图的1.5倍。
Bitmap withReflectionBitmap = Bitmap.createBitmap(width, (height
+ height / 2 + reflectionGap), Config.ARGB_8888);
// 构造函数传入Bitmap对象，为了在图片上画图
Canvas canvas = new Canvas(withReflectionBitmap);
// 画原始图片
canvas.drawBitmap(originalBitmap, 0, 0, null);
// 画间隔矩形
Paint defaultPaint = new Paint();
canvas.drawRect(0, height, width, height + reflectionGap, defaultPaint);
// 画倒影图片
canvas.drawBitmap(reflectionBitmap, 0, height + reflectionGap, null);
// 实现倒影效果
Paint paint = new Paint();
0, withReflectionBitmap.getHeight(), 0x70ffffff, 0x00ffffff,
TileMode.MIRROR);
paint.setXfermode(new PorterDuffXfermode(Mode.DST_IN));
// 覆盖效果
canvas.drawRect(0, height, width, withReflectionBitmap.getHeight(), paint);
return withReflectionBitmap;
}
}```

2.setXfermode

```Canvas canvas = new Canvas(bitmap1);
paint.setXfermode(new PorterDuffXfermode(Mode.SRC_IN));