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;
//画变换的一半
//先旋转,再裁切,再使用camera执行3D动效,**然后保存camera效果**,最后再旋转回来
canvas.save();
camera.save();
canvas.translate(centerX, centerY);
canvas.rotate(-degreeZ);
camera.rotateY(degreeY);
camera.applyToCanvas(canvas);
//计算裁切参数时清注意,此时的canvas的坐标系已经移动
canvas.clipRect(0, -centerY, centerX, centerY);
canvas.rotate(degreeZ);
canvas.translate(-centerX, -centerY);
camera.restore();
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
//画不变换的另一半
canvas.save();
camera.save();
canvas.translate(centerX, centerY);
canvas.rotate(-degreeZ);
//计算裁切参数时清注意,此时的canvas的坐标系已经移动
canvas.clipRect(-centerX, -centerY, 0, centerY);
//此时的canvas的坐标系已经旋转,所以这里是rotateY
camera.rotateY(fixDegreeY);
camera.applyToCanvas(canvas);
canvas.rotate(degreeZ);
canvas.translate(-centerX, -centerY);
camera.restore();
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
首先,解释下为什么用的是 canvas.clipRect(-centerX, -centerY, 0, centerY);而不是canvas.clipRect(0, -bitmapHeight/2, bitmapWidth/2, bitmapHeight/2);
我们应该意识到clipRect的行为不是真的裁切了图片,而是让图片的一小部分显示在方框里。因此,如果采取了canvas.clipRect(0, -bitmapHeight/2, bitmapWidth/2, bitmapHeight/2);你会发现是这样的效果
其实是因为剪裁的框框不够大,把边角裁掉了
image.png
需要注意的是canvas的旋转,旋转的不是坐标系。要证明这个很简单,我们在rotate前先裁剪。
canvas.save();
camera.save();
canvas.translate(centerX, centerY);
//canvas.rotate(-degreeZ);
camera.rotateY(0);
camera.applyToCanvas(canvas);
//计算裁切参数时清注意,此时的canvas的坐标系已经移动
//canvas.clipRect(0, -centerY, centerX, centerY);
canvas.rotate(270);
canvas.clipRect(0, -centerY, centerX, centerY);
canvas.translate(-centerX, -centerY);
camera.restore();
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
效果是这样的
image.png
当我们在rotate后再裁剪
canvas.save();
camera.save();
canvas.translate(centerX, centerY);
//canvas.rotate(-degreeZ);
camera.rotateY(0);
camera.applyToCanvas(canvas);
//计算裁切参数时清注意,此时的canvas的坐标系已经移动
canvas.clipRect(0, -centerY, centerX, centerY);
canvas.rotate(270);
//canvas.clipRect(0, -centerY, centerX, centerY);
canvas.translate(-centerX, -centerY);
camera.restore();
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
image.png
我们发现这两者有着区别,原因就是rotate旋转的不是坐标系,而是当前的画面。
实现三维旋转(0度)并裁切的效果
canvas.save();
camera.save();
canvas.translate(centerX, centerY);
canvas.rotate(-degreeZ);
camera.rotateY(0);
camera.applyToCanvas(canvas);
//计算裁切参数时清注意,此时的canvas的坐标系已经移动
canvas.clipRect(0, -centerY, centerX, centerY);
canvas.rotate(degreeZ);
//canvas.clipRect(0, -centerY, centerX, centerY);
canvas.translate(-centerX, -centerY);
camera.restore();
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
GIF2.gif
实现三维的旋转,这里需要注意的是如果把 camera.rotateY(-45);设为0,整个画面看起来时不动的,但其实它在旋转。
canvas.save();
camera.save();
canvas.translate(centerX, centerY);
canvas.rotate(-degreeZ);
camera.rotateY(-45);
camera.applyToCanvas(canvas);
//计算裁切参数时清注意,此时的canvas的坐标系已经移动
//canvas.clipRect(0, -centerY, centerX, centerY);
canvas.rotate(degreeZ);
//canvas.clipRect(0, -centerY, centerX, centerY);
canvas.translate(-centerX, -centerY);
camera.restore();
canvas.drawBitmap(bitmap, x, y, paint);
canvas.restore();
GIF3.gif
PS
如果你的图片文件没有建立分辨率文件夹分类放好,就会出现图片过大的情况。
网友评论