自定义View-Canvas对绘制的辅助clipXXX()和Matrix

前言

裁剪和几何变换,说实话平时用到的也不多,但确实也是很有意思的内容,一起来看一下吧

范围裁切

// 裁剪一个矩形
canvas.save();
canvas.clipRect(left, top, right, bottom);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();

// 裁剪一个Path, 能裁剪的形状更多一些
canvas.save();
canvas.clipPath(path);
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();

几何变换

几何变换使用大概分为三类:

  • 使用Canvas来做常见的二维变换
  • 使用Matrix来做常见和不常见的二维变换
  • 使用Camera来做三维变换
//1、使用Canvas来做常见的二维变换
    // 格式
    canvas.save();
    canvas.tranlate(200, 0);
    canvas.drawBitmap(bitmap, x, y, paint);
    canvas.restore();
    
    // 平移
    canvas.tranlate(x, y);
    // 旋转
    canvas.tranlate(degrees, centerX, centerY);
    // 缩放
    canvas.scale(sx, sy, centerX, centerY);
    // 错切
    canvas.skew(sx, sy)


//2、使用Matrix
    // 常见变换
    Matrix matrix = new Matrix();
    matrix.reset();
    matrix.postXXX();
    canvas.concat(matrix);
    
    // 自定义变换,通过点对点映射的方式设置变换,多点的映射,可以让绘制内容任意的扭曲
    matrix.setPolyToPoly(float[] src, int srcIndex, float[] dst, int dstIndex, int pointCount);
    

使用Camera来做三维变换

Camera的坐标系:X右正,Y上正,Z向内正

Camera在Z轴负方向上,也就是说始终在原点的Z轴上,往View上做一个投影

Camera旋转方向:

// camera.rotateX() 使用方法:
// 这个投影会是斜的,因为没有将canvas平移至原点

    canvas.save();
    camera.save();
    camera.rotateX(30);
    camera.applyToCanvas(canvas);
    camera.restore();
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();


// 需要在三维旋转之前将绘制内容的中心点移动到原点,投影后再移动回来
// canvas的几何变换顺序是反的,所以要把移到原点的代码写在下面,从中心移动回来的代码写在上面
    canvas.save();
    camera.save();
    camera.rotateX(30);
    canvas.tranlate(centerX, centerY);
    camera.applyToCanvas(canvas);
    canvas.tranlate(-centerX, -centerY);
    camera.restore();
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();


// Camera.translate()很少用到这个


// Camera.setLocation(x, y, z);

x,y一般不会变,z默认是-8,默认位置是8 x 72 = 576像素,往后移动可以修复糊脸问题

总结

1、范围裁切,可以裁切Rect或者任意的Path

2、二维变换:canvas可以做常见的二维变换,matrix可以做不常见的二维变换

3、三维变换:使用Camera来投影

贴个HenCoder的链接:自定义View-Canvas对绘制的辅助clipXXX()和Matrix

分割线---------------------------------------------------------------------------

实践

// 1 裁剪一个矩形出来
    int left = (getWidth() - bitmap.getWidth()) / 2;
    int top = (getHeight() - bitmap.getHeight()) / 2;

    canvas.save();
    canvas.clipRect(left + 50, top + 50, left + 300, left + 100);
    canvas.drawBitmap(bitmap, left, top, paint);
    canvas.restore(); 




// 2 裁剪一个圆和取圆相反的图形
    // add一个圆, 顺时针
    path1.addCircle(point1.x + 200, point1.y + 200, 150, Path.Direction.CW);
    canvas.save();
    canvas.clipPath(path1);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();

    // 取相反的图形
    path2.setFillType(Path.FillType.INVERSE_WINDING);
    path2.addCircle(point2.x + 200, point2.y + 200, 150, Path.Direction.CW);
    canvas.save();
    canvas.clipPath(path2);
    canvas.drawBitmap(bitmap, point2.x, point2.y, paint);
    canvas.restore();




// 3 向右平移canvas, 200像素
    canvas.save();
    canvas.translate(200, 0);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();




// 4 缩放canvas, x, y都扩大为原来的1.2倍
    int centerX1 = point1.x + bitmap.getWidth() / 2;
    int centerY1 = point1.y + bitmap.getHeight() / 2;
    canvas.save();
    canvas.scale(1.2f, 1.2f, centerX1, centerY1);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();




// 5 旋转canvas, 旋转180度
    int centerX1 = point1.x+ bitmap.getWidth() / 2;
    int centerY1 = point1.y+ bitmap.getHeight() / 2;
    canvas.save();
    canvas.rotate(180, centerX1, centerY1);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();




// 6 错切canvas, y错切0.5
    canvas.save();
    canvas.skew(0, 0.5f);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();




// 7 向右平移matrix, 200像素
    canvas.save();
    matrix.reset();
    matrix.postTranslate(200, 0);
    canvas.concat(matrix);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();




// 8 缩放matrix, x, y都扩大为原来的1.2倍
    int centerX1 = point1.x + bitmap.getWidth() / 2;
    int centerY1 = point1.y + bitmap.getHeight() / 2;
    canvas.save();
    matrix.reset();
    matrix.postScale(1.2f, 1.2f, centerX1, centerY1);
    canvas.concat(matrix);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();
    



// 9 旋转matrix, 旋转180度
    int centerX1 = point1.x + bitmap.getWidth() / 2;
    int centerY1 = point1.y + bitmap.getHeight() / 2;
    canvas.save();
    matrix.reset();
    matrix.postRotate(180, centerX1, centerY1);
    canvas.concat(matrix);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();




// 10 错切matrix, y错切0.5
    canvas.save();
    matrix.reset();
    matrix.postSkew(0, 0.5f);
    canvas.concat(matrix);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();




// 11 Camera在原点, 旋转图形, 沿x轴旋转30度后直接投影
    canvas.save();
    camera.save();
    camera.rotateX(30);
    camera.applyToCanvas(canvas);
    camera.restore();
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore(); 





// 12 修正版, Camera在原点, 旋转图形, 沿x轴旋转30度后, 将图形移到原点投影后再移回来
    int centerX1 = point1.x + bitmapWidth / 2;
    int centerY1 = point1.y + bitmapHeight / 2;

    camera.save();
    matrix.reset();
    camera.rotateX(30);
    camera.getMatrix(matrix);
    camera.restore();
    matrix.preTranslate(-centerX1, -centerY1);
    matrix.postTranslate(centerX1, centerY1);
    canvas.save();
    canvas.concat(matrix);
    canvas.drawBitmap(bitmap, point1.x, point1.y, paint);
    canvas.restore();





// 13 沿x轴旋转,糊脸修正
    // 通过属性动画, 改变degree属性
    // 注意设置camera的setLocation()方法设置距离Z轴的高度
    // onDraw() 方法中是Camera三维变换的代码




// 14 翻页效果,下半部分翻页
    // 设置动画代码省略
    // 关键代码
    // 算出几个重要的坐标点
        int bitmapWidth = bitmap.getWidth();
        int bitmapHeight = bitmap.getHeight();
        // 中心点
        int centerX = getWidth() / 2;
        int centerY = getHeight() / 2;
        // 图片左上角原点
        int x = centerX - bitmapWidth / 2;
        int y = centerY - bitmapHeight / 2;

        // 首先绘制上半部分
        canvas.save();
        canvas.clipRect(0, 0, getWidth(), centerY);
        canvas.drawBitmap(bitmap, x, y, paint);
        canvas.restore();

        // 绘制下半部分的旋转
        canvas.save();

        if (degree < 90) {
            // 旋转角度小于90,裁剪下半部分
            canvas.clipRect(0, centerY, getWidth(), getHeight());
        } else {
            // 旋转角度大于90,裁剪上半部分
            canvas.clipRect(0, 0, getWidth(), centerY);
        }

        camera.save();
        camera.rotateX(degree);
        canvas.translate(centerX, centerY);
        camera.applyToCanvas(canvas);
        canvas.translate(-centerX, -centerY);
        camera.restore();

        canvas.drawBitmap(bitmap, x, y, paint);
        canvas.restore();

 

要使用JMeter进行CSV文件压测,你需要按照以下步骤操作: 1. 准备CSV文件:首先,你需要准备一个包含测试数据的CSV文件。确保CSV文件的格式正确,并且数据按照正确的列进行排列。 2. 配置CSV数据集:在JMeter中,你可以使用CSV数据集配置元件来读取CSV文件并使用其中的数据进行压测。打开你的JMeter测试计划,右键点击“线程组”,选择“添加” -> “Config元件” -> “CSV数据集配置”。在CSV数据集配置的“文件名”字段中,输入CSV文件的路径。 3. 配置CSV数据集参数:在CSV数据集配置元件中,你可以设置一些参数来控制数据的读取方式。你可以根据需要设置以下参数:文件编码、变量名称、分隔符、引用字符等。确保这些参数与你的CSV文件的实际配置匹配。 4. 在压力机上启动JMeter服务:根据你的操作系统类型,在压力机上执行相应的命令来启动JMeter服务。如果你的压力机是Windows,使用命令:`jmeter-server.bat -Djava.rmi.server.hostname=压力机ip`。如果你的压力机是Linux或Mac,使用命令:`./jmeter-server -Djava.rmi.server.hostname=压力机ip`。确保将命令中的“压力机ip”替换为你的压力机的实际IP地址。 5. 启动JMeter压测:在本地机器上启动JMeter图形化界面,加载你的测试计划。然后,你可以开始设置你的压测场景,包括线程组、HTTP请求等。确保在需要使用CSV数据的地方使用正确的变量名称。 以上是使用JMeter进行CSV文件压测的步骤。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值