自定义View Canvas的范围裁切与几何变换

Canvas 对绘制的辅助--范围裁切与几何变换

1.范围裁切

范围裁切有两个方法:clipRect(),clipPath()
范围裁切就是将将画布裁切成指定的形状大小,然后在裁切后的画布上作图。

1.1 clipRect()

这里直接进行矩形裁切!

例:
Cavase.clipRect(left,top,right,bottom);

1.2 clipPath()

这里用户可以按照自己指定的图形进裁切!
例:

    canvas.save();  
    canvas.clipPath(path1);  
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);  
    canvas.restore();

    canvas.save();  
    canvas.clipPath(path2);  
    canvas.drawBitmap(bitmap, point2.x, point2.y, paint);  
    canvas.restore(); 
image.png

2.几何变换

几何变换大致分为三类
• 使用canvas来做常见的二维变换
• 使用matrix来做常见和不常见的二维变换
• 使用camera来做三维变换

2.1 使用canvas来做常见的二维变换

2.1.1 使用canvas.translate(float dx,float dy)平移
参数dx和dy表示横向和纵向的位移。
这个时候可以简单理解为将物体的左上顶点平移水平平移x距离,竖直方向平移y距离。

2.1.2 Canvas.rotate(float degrees,float px,float py)旋转
degrees为旋转角度(旋转方向为顺时针),px,py为旋转轴心。
例:

    canvas.save();  
    canvas.rotate(45, centerX, centerY);  
    canvas.drawBitmap(bitmap, x, y, paint);  
    canvas.restore();  
image.png

2.1.3 canvas.scale(float sx,float sy,float px,float py) 缩放
参数 sx sy 为横向缩放和纵向缩放倍数,px,py是缩放轴心。
例:

    canvas.save();  
    canvas.scale(1.3f, 1.3f, x + bitmapWidth / 2, y + bitmapHeight / 2);  
    canvas.drawBitmap(bitmap, x, y, paint);  
    canvas.restore(); 
image.png

2.1.4 canvas.skew(float sx,float sy,float sy)错切
参数:sx sy 为x方向和y方向错切的错切系数
例:

    canvas.save();  
    canvas.skew(0, 0.5f);  
    canvas.drawBitmap(bitmap, x, y, paint);  
    canvas.restore(); 
image.png
2.2 使用Matrix 做变换

2.2.1 使用Matrix 做常见变换
1.创建Matrix对象
2.调用Matrix的 pre/postTranslate/Rotate/Scale/Skew() 方法来设置几何变换
3.使用Canvas.setMatrix(matrix)或Canvas.concat(matrix)来将几何变换应用到Canvas中。

Canvas.setMatrix(matrix) 和 Canvas.concat(matrix) 方法区别

• Canvas.setMatrix(matrix):用 Matrix 直接替换 Canvas 当前的变换矩阵,即抛弃 Canvas 当前的变换,改用 Matrix 的变换(注:不同的系统中 setMatrix(matrix) 的行为可能不一致,所以还是尽量用 concat(matrix) 吧);
• Canvas.concat(matrix):用 Canvas 当前的变换矩阵和 Matrix 相乘,即基于 Canvas 当前的变换,叠加上 Matrix 中的变换。

2.2.2使用Matrix 来做自定义变换
2.2.2.1 Matrix.setPolyToPoly(float[] src,int srcIndex,float[] dst,int dstIndex,int pointCount)用点对点映射的方式设置变换。

poly 就是「多」的意思。setPolyToPoly() 的作用是通过多点的映射的方式来直接设置变换。「多点映射」的意思就是把指定的点移动到给出的位置,从而发生形变。例如:(0, 0) -> (100, 100) 表示把 (0, 0) 位置的像素移动到 (100, 100) 的位置,这个是单点的映射,单点映射可以实现平移。而多点的映射,就可以让绘制内容任意地扭曲。

例:

    Matrix matrix = new Matrix();  
    float pointsSrc = {left, top, right, top, left, bottom, right, bottom};  
    float pointsDst = {left - 10, top + 50, right + 120, top - 90, left + 20, bottom + 30, right + 20, bottom + 60};

    ...

    matrix.reset();  
    matrix.setPolyToPoly(pointsSrc, 0, pointsDst, 0, 4);

    canvas.save();  
    canvas.concat(matrix);  
    canvas.drawBitmap(bitmap, x, y, paint);  
    canvas.restore(); 
image.png

参数里,src 和 dst 是源点集合目标点集;srcIndex 和 dstIndex 是第一个点的偏移;pointCount 是采集的点的个数(个数不能大于 4,因为大于 4 个点就无法计算变换了)。
注:使用此方法最好关闭硬件加速,单纯是drawBitmap可以不用关,其他必须关,不然效果不理想

2.3 使用Camera 做三维变换 Camera 的变化有 旋转,平移,移动相机

2.3.1 Camera.rorate*() 三维旋转
rorateX(deg)沿X轴旋转
rorateY(deg)沿Y轴旋转
rorateZ(deg)沿Z轴旋转
Rorate(x,y,z)沿X,Y,Z轴旋转

2.3.2 Camera.translate(float x,float y,float z)移动
2.3.3 Camera.setLocation(x,y,z)设置虚拟相机的位置
这里,设置Camera虚拟相机位置的参数不是像素,是英寸。

这种设计源自 Android 底层的图像引擎 Skia 。在 Skia 中,Camera 的位置单位是英寸,英寸和像素的换算单位在 Skia 中被写死为了 72 像素,而 Android 中把这个换算单位照搬了过来。是的,它。写。死。了。

在 Camera 中,相机的默认位置是 (0, 0, -8)(英寸)。8 x 72 = 576,所以它的默认位置是 (0, 0, -576)(像素)。
在Camera.setLocation(x,y,z)中,x与y一般不会改动!

如果绘制的内容过大,当它翻转起来的时候,就有可能出现图像投影过大的「糊脸」效果。而且由于换算单位被写死成了 72 像素,而不是和设备 dpi 相关的,所以在像素越大的手机上,这种「糊脸」效果会越明显。


image.png

使用Camera.setLocation(0,0,x)可以修复这个问题


image.png

你可能感兴趣的:(自定义View Canvas的范围裁切与几何变换)