本节引言:
在Canvas的API文档中,我们看到这样一个方法:drawBitmap(Bitmap bitmap, Matrix matrix, Paint paint)
这个Matrix可是有大文章的,前面我们在学Paint的API中的ColorFilter中曾讲过ColorMatrix 颜色矩阵,一个4 * 5 的矩阵,我们可以通过修改矩阵值来修改色调,饱和度等! 而今天讲的这个Matrix可以结合其他API来控制图形,组件的变换。比如Canvas就提供了上面的 这个drawBitmap来实现矩阵变换的效果!下面我们来慢慢研究这个东东~
1.Matrix中的几个常用的变换方法
- setTranslate(float dx, float dy):控制Matrix进行平移
- setRotate(float degrees, float px, float py):旋转,参数依次是:旋转角度,轴心(x,y)
- setScale(float sx, float sy, float px, float py):缩放, 参数依次是:X,Y轴上的缩放比例;缩放的轴心
- setSkew(float kx, float ky):倾斜(扭曲),参数依次是:X,Y轴上的缩放比例
其实和Canvas变换的方法基本一致,在为Matrix设置了上面的变换后,调用Canvas的 drawBitmap()方法调用矩阵就好~
2.Matrix使用示例:
运行效果图:
代码实现:
MyView.java:
public class MyView extends View {
private Bitmap mBitmap;
private Matrix matrix = new Matrix();
private float sx = 0.0f; //设置倾斜度
private int width,height; //位图宽高
private float scale = 1.0f; //缩放比例
private int method = 0;
public MyView(Context context) {
this(context, null);
}
public MyView(Context context, AttributeSet attrs) {
super(context, attrs);
init();
}
public MyView(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
}
private void init() {
mBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.img_meizi);
width = mBitmap.getWidth();
height = mBitmap.getHeight();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
switch (method){
case 0:
matrix.reset();
break;
case 1:
sx += 0.1;
matrix.setSkew(sx,0);
break;
case 2:
sx -= 0.1;
matrix.setSkew(sx,0);
break;
case 3:
if(scale < 2.0){
scale += 0.1;
}
matrix.setScale(scale,scale);
break;
case 4:
if(scale > 0.5){
scale -= 0.1;
}
matrix.setScale(scale,scale);
break;
}
//根据原始位图与Matrix创建新图片
Bitmap bitmap = Bitmap.createBitmap(mBitmap,0,0,width,height,matrix,true);
canvas.drawBitmap(bitmap,matrix,null); //绘制新位图
}
public void setMethod(int i){
method = i;
postInvalidate();
}
}
MainActivity.java:
public class MainActivity extends AppCompatActivity implements View.OnClickListener{
private Button btn_reset;
private Button btn_left;
private Button btn_right;
private Button btn_zoomin;
private Button btn_zoomout;
private MyView myView;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
bindViews();
}
private void bindViews() {
btn_reset = (Button) findViewById(R.id.btn_reset);
btn_left = (Button) findViewById(R.id.btn_left);
btn_right = (Button) findViewById(R.id.btn_right);
btn_zoomin = (Button) findViewById(R.id.btn_zoomin);
btn_zoomout = (Button) findViewById(R.id.btn_zoomout);
myView = (MyView) findViewById(R.id.myView);
btn_reset.setOnClickListener(this);
btn_left.setOnClickListener(this);
btn_right.setOnClickListener(this);
btn_zoomin.setOnClickListener(this);
btn_zoomout.setOnClickListener(this);
}
@Override
public void onClick(View v) {
switch (v.getId()){
case R.id.btn_reset:
myView.setMethod(0);
break;
case R.id.btn_left:
myView.setMethod(1);
break;
case R.id.btn_right:
myView.setMethod(2);
break;
case R.id.btn_zoomin:
myView.setMethod(3);
break;
case R.id.btn_zoomout:
myView.setMethod(4);
break;
}
}
}
布局就不写了,很简单
3.drawBitmapMash扭曲图像
在API文档中还有这样一个方法: drawBitmapMesh(Bitmap bitmap, int meshWidth, int meshHeight, float[] verts, int vertOffset, int[] colors, int colorOffset, Paint paint)
参数依次是:
- bitmap:需要扭曲的原位图
- meshWidth/meshHeight:在横/纵向上把原位图划分为多少格
- verts:长度为(meshWidth+1)*(meshHeight+2)的数组,他记录了扭曲后的位图各顶点(网格线交点) 位置,虽然他是一个一维数组,但是实际上它记录的数据是形如(x0,y0),(x1,y1)..(xN,Yn)格式的数据, 这些数组元素控制对bitmap位图的扭曲效果
- vertOffset:控制verts数组从第几个数组元素开始对bitmap进行扭曲(忽略verOffset之前数据 的扭曲效果)
代码示例:
运行效果图:
网友评论