2012-05-04 6 views
5

ズームとパンが可能な画像を表示しようとしています。以下のコードでは、3つのアクションすべてが仕事の種類ですが、それらはお互いに影響します。ここでアンドロイドキャンバスでのビットマップの回転、平行移動、スケーリングの同時実行

は私が達成したいものです。
1.画像内の所望の場所にパン
3.中央の画像の同じ部分を残して画面
2.スケールの中心の周りを回転しますここで

は、実際には以下のコードで何が起こっているかである。意図したとおりに
1回転は
2.スケーリング作品画面の中央付近に、動作しますが、それは絵の 中心付近スケール
3.翻訳のみ回転し、後 angleがゼロであれば、私が最初に翻訳した場合、それ以外の場合は、間違った方向

// the center of the view port 
float centerX = screen.right/2; 
float centerY = screen.bottom/2; 

Matrix m = new Matrix(); 
m.preRotate(angle, centerX, centerY); 
m.preScale(mScaleFactor, mScaleFactor, centerX, centerY); 

// scaling the amount of translation, 
// rotating the translation here gave crazy results 
float x = mPosX/mScaleFactor; 
float y = mPosY/mScaleFactor; 
m.preTranslate(x, y); 

canvas.drawBitmap(pic, m, null); 

に動いて、意図した、とのように動作しますが、翻訳が意図したとおりに動作しますが、回転はの中心の周りではありませんもうビューポート。

どのように3つの変換を互いに影響を与えずに適用できますか?

答えて

1

イメージの中央付近のスケーリングについてはわかりませんが、翻訳が間違った方向にあるのは、イメージを回転させた結果ではなく翻訳されていないためです。また、行列オブジェクトは直接affine transformationを適用する方法を持っているん

float x = (mPosX*(cos(angle) + sin(angle))/mScaleFactor; 
float y = (mPosY*(cos(angle) - sin(angle))/mScaleFactor; 
m.preTranslate(x, y); 

:たぶん、このような何かを試してみてください?そのため、操作の順序について考える必要はありません。

アフィン変換は次のようなものになります。

M = |mScaleFactor*cos(angle)  sin(angle)   x| 
    |  -sin(angle)   mScaleFactor*cos(angle) y| 
    |   0       0    1| 

しかし、あなたが最初にそうようpreTranslate()関数を使用する必要があるので、これは画像の角を回って回転します:

Mt.preTranslate(-centerX,-centerY); 

そして、Mを適用する前に写真を貼り付けてから、-Mtを適用する必要があります。

+0

回転を回転するだけで回転がオフセットされているように見えますが、これは私の元気ですd。 Androidの行列は3x3なので、彼らはすでにアフィン変換ですか? – modemuser

+0

preRotate、preScaleメソッドを使用する代わりに、マトリックスを直接設定してみてください。したがって、あなたのマトリックスは、上記の投稿の編集のようなものにする必要があります – Dan

+0

この行列では、パンニングは機能しますが、スケーリングでもピクチャが回転し、回転もピクチャのスケーリングが行われ、回転がピクチャのコーナーを中心に行われます。これは、モルタルのようなものですが、あなたのご意見に感謝します。 – modemuser

関連する問題