前言
上一节学习了各种图形的绘制方法,最后用到了matrix,不明白它的作用,本节将学习matrix的用法
Matrix
Matrix–坐标变换矩阵
矩阵,大学的线性代数里学过(已经忘的差不多了),不知道的可以看这里矩阵
android里的矩阵主要用来对图形进行坐标变化,将原来的坐标点转移到新的坐标点,总共分为rotate(旋转),translate(平移),scale(缩放)和skew(倾斜)四种
坐标变换矩阵是一个3*3的矩阵,
Matrix 由 9 个 float 值构成,是一个 3*3 的矩阵。如下图
cosX -sinX translateX
sinY cosY translateY
0 0 scale
上面的 sinX 和 cosX ,表示旋转角度的 cos 值和 sin 值,注意,旋转角度是按顺时针方向计算的。 translateX 和 translateY 表示 x 和 y 的平移量。 scale 是缩放的比例, 1 是不变, 2 是表示缩放 1/2
下面依次对上面四种效果进行矩阵举例
rotate(旋转)
假设旋转角度为90°,cosX=0,sinX=1,此时的矩阵应该为
0,-1,0
1,0,0
0,0,1
代码如下:
float cos = (float) Math.cos(Math.PI / 2);
float sin = (float) Math.sin(Math.PI / 2);
Bitmap bitmap = BitmapFactory.decodeResource(getResources(), R.drawable.ic_launcher);
matrix.setValues(new float[]{
cos, -sin, 0,
sin, cos, 0,
0, 0, 1
});
canvas.drawBitmap(bitmap, matrix, null);
translate(平移)
x轴,及Y轴各便宜200
matrix.setValues(new float[]{
1, 0, 200,
0, 1, 200,
0, 0, 1
});
scale(缩放)
缩小一倍
matrix.setValues(new float[]{
1, 0, 0,
0, 1, 0,
0, 0, 2
});
skew(倾斜)
平行于X轴
matrix.setValues(new float[]{ 1, k, 200, 0, 1, 200, 0, 0, 1 });
平行于Y轴
matrix.setValues(new float[]{ 1, 0, 200, k, 1, 200, 0, 0, 1 });
上述四种方式对于Matrix API都提供了相应的方法直接调用分别为:
setRotate(float degrees, float px, float py) 旋转
setTranslate(float dx, float dy) 平移
setScale(float sx, float sy, float px, float py) 放大
setSkew(float kx, float ky, float px, float py) 斜切
相信了解了上述原理后,再看这些API方法,应该很容易就知道了
现学现卖–倒影图
//获得带倒影的图片方法
public Bitmap createReflectionImageWithOrigin(Bitmap bitmap) {
// 图片与倒影之间的距离间隔
final int reflectionGap = 2;
// 原图的宽度
int width = bitmap.getWidth();
// 原图的高度
int height = bitmap.getHeight();
// 图片旋转,缩放等控制对象
Matrix matrix = new Matrix();
// 缩放(这里pre,set,post三种效果是不一样的,注意区别)
matrix.preScale(1, -1);
matrix.postSkew(-0.2f, 0);
// 创建一个初始的倒影位图
Bitmap reflectionImage = Bitmap.createBitmap(bitmap, 0, height / 2, width, height / 2, matrix, false);
// 新建一个宽度为原图宽度,高度为原图高度的3/2的位图,用于绘制新的位图,即整体的效果图位图对象
Bitmap bitmapWithReflection = Bitmap.createBitmap(width, (height + height / 2), Bitmap.Config.ARGB_8888);
// 由该位图对象创建初始画布(规定了画布的宽高)
Canvas canvas = new Canvas(bitmapWithReflection);
// 在该画布上绘制原图
canvas.drawBitmap(bitmap, 0, 0, null);
// 创建一个画笔
Paint deafalutPaint = new Paint();
// 绘制该倒影图于间隔图的下方
canvas.drawBitmap(reflectionImage, 0, height + reflectionGap, null);
// 创建一个画笔
Paint paint = new Paint();
// 创建一个线性渐变对象
LinearGradient shader = new LinearGradient(
0, bitmap.getHeight(),
0, bitmapWithReflection.getHeight() + reflectionGap,
0x70ffffff, 0x00ffffff,
Shader.TileMode.CLAMP
);
// 把渐变效果应用在画笔上
paint.setShader(shader);
// Set the Transfer mode to be porter duff and destination in
// 未知
paint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
// Draw a rectangle using the paint with our linear gradient
// 绘制出该渐变效果,也就是最终的倒影效果图
canvas.drawRect(0, height, width, bitmapWithReflection.getHeight() + reflectionGap, paint);
// 返回
return bitmapWithReflection;
}
效果图: