Смещение растрового изображения только в вертикальном направлении
Я хочу исказить (поправьте меня, если это не правильное слово) растровое изображение, чтобы оно казалось глубоким. Хороший способ визуализировать то, что я прошу, - это как титры "Звездных войн" наклонены, чтобы показать глубину.
Я попробовал следующее:
canvas.getMatrix().postSkew(kx,ky,px,py);
И
canvas.skew(sx,sy);
Но у меня не было большого успеха. Приведенные выше методы, по-видимому, всегда преобразуют растровое изображение в параллелограмм. Есть ли способ преобразовать растровое изображение в трапецию?
Вот фрагмент кода, который я взял из примеров, на которые указал мне Ромен.
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();
3 ответа:
Вы не можете достичь желаемого эффекта с помощью функции skew (). Однако для достижения этого эффекта можно использовать объект камеры и 3D-вращения. Камера сгенерирует матрицу для вас, которую вы затем можете применить на холсте. Обратите внимание, что результат не будет перспективно правильным, но достаточно хорошим для вашей цели. Так, например, выполняются 3D-вращения в лаунчере Honeycomb (и многих других приложениях.)
Я потратил много времени, работая над этим сегодня (столкнулся с той же проблемой) и придумал код ниже.
Ключевая вещь, которую нужно отметить, вам нужно установить preTranslate() и postTranslate() в центре (или где-то еще) Вашей области холста. Это, по-видимому, означает,что он использует центр изображения для применения преобразования из, а не верхний левый угол (x=0, y=0) по умолчанию. Вот почему вы получите параллелограмм вместо того, что вы ожидали бы, трапеция (Спасибо за учит меня их именам).
Еще одна важная вещь, которую я подобрал, - это функции сохранения/восстановления на холсте/камере. В принципе, если вы вызываете функции поворота последовательно три раза без восстановления состояния каждый раз, вы будете продолжать вращать свой объект вокруг и вокруг каждый раз, когда вы рисуете. Может быть, вы этого и хотите, но в моем случае я этого не делал. То же самое относится и к холсту, поскольку вы в основном применяете матрицу от объекта камеры к холсту и его нужно сбросить, иначе произойдет то же самое.
Надеюсь, это кому-то поможет, это не очень хорошо документировано для начинающих. Совет всем, кто читает это, проверьте папку APIDemos в образцах SDK. Существует 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(); }