初识Matrix
第一次见到Matrix是在图片缩放的时候,Matrix(矩阵),在网上搜索一番,觉得还是直接写下记录一下方便以后复习翻阅
public class MyView extends View {
Bitmap mBitmap;
public MyView(Context context) {
super(context);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
public Bitmap getBitmap() {
return mBitmap;
}
public void setBitmap(Bitmap bitmap) {
mBitmap = bitmap;
}
public boolean isEmpty() {
return mBitmap == null;
}
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
Matrix matrix = new Matrix();
canvas.drawBitmap(mBitmap, matrix, null);
}
}
}
xml布局
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/activity_main"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="com.example.jinxiong.matric.MainActivity">
<com.example.jinxiong.matric.MyView
android:layout_width="match_parent"
android:layout_height="match_parent"
android:id="@+id/myImageView"
/>
</RelativeLayout>
Activity
public class MainActivity extends AppCompatActivity {
ImageLoader mImageLoader;
MyView mImageView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
ImageLoaderConfiguration imageLoaderConfiguration = ImageLoaderConfiguration.createDefault(this);
ImageLoader.getInstance().init(imageLoaderConfiguration);
mImageLoader = ImageLoader.getInstance();
mImageView = (MyView) this.findViewById(R.id.myImageView);
Bitmap bitmap = mImageLoader.loadImageSync("drawable://" + R.drawable.test);
mImageView.setBitmap(bitmap);
}
}
可以看到这张图片是大于手机屏幕的,需要对图片进行缩小,那么就要使用到Matrix了
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f);
canvas.drawBitmap(mBitmap, matrix, null);
}
}
那么就可以看到
那么Matrix那么厉害,他究竟是什么?
走进Matrix
matrix就是矩阵的意思,
正常我们通过
Matrix matrix = new Matrix();
创建的矩阵式单位矩阵:
我们可以通过
matrix.toShortString()
打印出来
[1.0, 0.0, 0.0][0.0, 1.0, 0.0][0.0, 0.0, 1.0]
我认为Matrix最重要的就是实现变换,基本的变换有四种
1. 缩放
2. 错切
3. 平移
4. 旋转
参数控制:
缩放
在初次创建Matrix 对象的时候,Matrix的缩放两个参数都是1,表示按原本尺寸显示,
matrix.setScale();
matrix.postScale();
matrix.preScale();
有这三个方法,参数都是一样,先说下两个参数的情况
setScale 就是在你原有的矩阵中 插入两个值,一个是1行2列 ,一个是2行1列中的值
而preScale 就是矩阵的乘,把原有的矩阵放在乘的左边,目标矩阵放在右边(因为矩阵的左乘和右乘是不一样的),
左边的第一行与右边的第一列的值相乘相加后变成结果矩阵的第一行第一列的值,左边第一行与右边第二列的值相乘相加结果变成借股票矩阵的第一行第二列的值,左边的第一行和右边的第三列相乘相加的值变为结果矩阵的第一行第三列的值,以此类推
而postScale 也是这样,只不过把源矩阵和目标矩阵的位置交换,那么结果自然是不一样的了
而当它为四个参数的时候
public void setScale(float sx, float sy, float px, float py) {
native_setScale(native_instance, sx, sy, px, py);
}
后面两个新参数就是缩放中心的坐标,如果使用两位参数的setScale的话,默认的缩放中心坐标就是(0,0)
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
Matrix matrix = new Matrix();
matrix.setScale(0.5f, 0.5f, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
canvas.drawBitmap(mBitmap, matrix, null);
}
}
将刚刚那张图片以图片中心为缩放中心缩小一半,
对于这三种方法设置图片的缩放,对于set方法,是直接将值付给相应的矩阵的位置的值,对源矩阵来说,改变的只是那两个缩放的值,但是对于pre 和 post的话,因为涉及到矩阵的乘法,还是会对源矩阵一些本来的值会造成影响,可能这并不是你想要的,至于什么时候使用哪一种,具体还是看自己想要怎么样
错切
错切也有三个方法和两种参数格式,跟scale 是一样的,这里就以setSkew为例子
matrix.setSkew(0.5f,0f);
matrix.setSkew(0f,0.5f);
matrix.setSkew(0.5f,0.5f);
matrix.setSkew(0.5f, 0.5f, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
旋转
旋转也是对应着三个方法
matrix.setRotate(45);
原点为中心旋转45度
matrix.setRotate(180, mBitmap.getWidth() / 2, mBitmap.getHeight() / 2);
图片中心为中心,180度
平移
这个也是很简单的方法
matrix.setTranslate(0,200);
这里的translation 和 view.setTranslation 相似,但是移动 的偏移量是不同的位置
setPolyToPoly
这个特效怎么实现尼 ,答案就是setPolyToPoly
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
Matrix matrix = new Matrix();
float[] src = new float[]{
0,0,
mBitmap.getWidth(),0,
mBitmap.getWidth(),mBitmap.getHeight(),
0,mBitmap.getHeight()
};
float[] dst = new float[]{
0, 0,
mBitmap.getWidth()/2, 100,
mBitmap.getWidth()/2, mBitmap.getHeight() - 100,
0, mBitmap.getHeight()
};
matrix.setPolyToPoly(src, 0, dst, 0, 4);
canvas.drawBitmap(mBitmap, matrix, null);
}
}
poly就是多边形的意思,
/**
* Set the matrix such that the specified src points would map to the
* specified dst points. The "points" are represented as an array of floats,
* order [x0, y0, x1, y1, ...], where each "point" is 2 float values.
*
* @param src The array of src [x,y] pairs (points)
* @param srcIndex Index of the first pair of src values
* @param dst The array of dst [x,y] pairs (points)
* @param dstIndex Index of the first pair of dst values
* @param pointCount The number of pairs/points to be used. Must be [0..4]
* @return true if the matrix was set to the specified transformation
*/
public boolean setPolyToPoly(float[] src, int srcIndex,
float[] dst, int dstIndex,
int pointCount)
src:代表的是一个坐标数组,这个多边形的点的坐标,srcIndex代表的是从前面的数组哪一个下标开始,而
dst就是你想要变成的多边形的坐标数组,
setRectToRect
也是使用一个源矩形和目标矩形进行变换,这是使图片居中(感觉微信的图片是不是这样实现尼?)
@Override
protected void onDraw(Canvas canvas) {
if (mBitmap != null) {
Matrix matrix = new Matrix();
RectF src = new RectF(0, 0, mBitmap.getWidth(), mBitmap.getHeight());
RectF dst = new RectF(0, 0, getWidth(), getHeight());
matrix.setRectToRect(src, dst, Matrix.ScaleToFit.CENTER);
canvas.drawBitmap(mBitmap, matrix, null);
}
}
}
最后
基本的使用就是这样 ,更多详细可以看着个大神blog
http://www.gcssloop.com/customview/Matrix_Basic
http://www.gcssloop.com/customview/Matrix_Method