我想歪曲(纠正我,如果这不是正确的单词)位图,以便它看起来有深度。可视化我要求的一个好方法是星球大战的信用角度如何显示深度。
我尝试了以下内容:
canvas.getMatrix().postSkew(kx,ky,px,py);
和
canvas.skew(sx,sy);
但我没有取得多大成功。上述方法似乎总是将位图转换为平行四边形。有没有办法将位图转换为梯形?
以下是我从Romain向我指出的示例中获取的一段代码。
canvas.rotate(-mOrientation[0] + mHeading, mCenterX, mCenterY);
camera.save();
if (mReverse) {
camera.translate(0.0f, 0.0f, mDepthZ * interpolatedTime);
} else {
camera.translate(0.0f, 0.0f, mDepthZ * (1.0f - interpolatedTime));
}
camera.rotateX(mOrientation[1]);
camera.applyToCanvas(canvas);
canvas.drawPath(mPath, mPaint);
canvas.drawCircle(mCenterX, mCenterY, mRadius - 37, mPaint);
camera.restore();
答案 0 :(得分:12)
我今天花了很多时间研究这个问题(遇到了同样的问题),并提出了下面的代码。
需要注意的一点是,您需要将preTranslate()和postTranslate()设置为Canvas区域的中心(或其他位置)。这似乎意味着它默认使用图像的中心来应用变换,而不是左上角(x = 0,y = 0)。这就是为什么你会得到一个平行四边形,而不是你想要的,一个梯形(感谢你教我的名字)。
我选择的另一件重要事情是Canvas / Camera上的Save / Restore功能。基本上,如果你连续三次调用旋转功能而不是每次都恢复状态,那么每次绘制时你都会继续旋转你的物体。这可能就是你想要的,但我当然不会这样。同样适用于画布,因为您基本上将Matrix从Camera对象应用到Canvas,它需要重置,否则会发生同样的事情。
希望这有助于某些人,这对于初学者来说并没有很好的记录。向阅读此内容的任何人提示,请查看SDK示例中的APIDemos文件夹。还有一个Rotate3dAnimation.java文件也可以证明这一点。
//Snippet from a function used to handle a draw
mCanvas.save(); //save a 'clean' matrix that doesn't have any camera rotation in it's matrix
ApplyMatrix(); //apply rotated matrix to canvas
Draw(); //Does drawing
mCanvas.restore(); //restore clean matrix
//
public void ApplyMatrix() {
mCamera.save();
mCamera.rotateX(-66);
mCamera.rotateY(0);
mCamera.rotateZ(0);
mCamera.getMatrix(mMatrix);
int CenterX = mWidth / 2;
int CenterY = mHeight / 2;
mMatrix.preTranslate(-CenterX, -CenterY); //This is the key to getting the correct viewing perspective
mMatrix.postTranslate(CenterX, CenterY);
mCanvas.concat(mMatrix);
mCamera.restore();
}
答案 1 :(得分:6)
使用skew()无法达到所需的效果。但是,您可以使用Camera对象和3D旋转来实现此效果。相机将为您生成一个矩阵,然后您可以在画布上应用。请注意,结果不是透视正确的,但足以满足您的目的。这就是如何在Honeycomb的Launcher中完成3D旋转(以及许多其他应用程序。)
答案 2 :(得分:1)
我认为“星球大战效果”不是affine transformation,我认为这是Matrix
支持的唯一操作。