私は同じ問題を抱えていて、変換後に長方形の座標を見つけることで解決しました。
これらの座標を見つけるには、何が起こっているのかを理解する必要があります。マトリックスは、クワッドの 4 つのエッジ ポイントと対応するポイントによって与えられる透視変換を定義します。次のコードでこれを行いました。
Matrix matrix = new Matrix();
float[] dst = new float[] {
0,
0,
bitmap.getWidth(),
0,
bitmap.getWidth(),
bitmap.getHeight(),
0,
bitmap.getHeight()
};
float[] src = new float[] {
boundingQuad.topLeft.x,
boundingQuad.topLeft.y,
boundingQuad.topRight.x,
boundingQuad.topRight.y,
boundingQuad.bottomRight.x,
boundingQuad.bottomRight.y,
boundingQuad.bottomLeft.x,
boundingQuad.bottomLeft.y
};
matrix.setPolyToPoly(src, 0, dst, 0, src.length >> 1);
これは、(たとえば) クワッドの左上のポイントがポイント (0,0) に変換されることを意味します。これを確認するには、行列をポイントに適用し、結果の値を確認します。マトリックスを適用するには、メソッドを使用できますmapPoints(...)
。定義された変換マトリックスは正常に機能します。(一見すると) この変換の奇妙な動作は、ビットマップの作成に起因します。
return Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
結果のビットマップは間違っているように見えます。これは、一部のポイント (たとえば、クワッドの左上のポイントの左側にあるすべてのポイント) が負の座標に変換され、ビットマップに何かを描画する場合は座標が正でなければならないためです。 . このため、変換されたポイントがシフトされ、ビットマップ内の変換されたポイントの座標が奇妙になります。
結論: ポイントは新しい座標に正しく変換されますが、表示できません。このため、ポイントはシフトされ、ビットマップ内の変換されたポイントのシフトされた座標は、変換マトリックスで定義されている座標ではありません。
この問題を解決し、ビットマップ内の変換されたポイントの適切な座標を取得するには、シフトの値を計算する必要があります。シフトは、x 値と y 値で構成されます。
x 値を計算するために、元の画像の左上の点の x 値と左下の点の x 値を、以前に定義した行列で変換しました。左上のポイントまたは左下のポイントのいずれかが、結果のビットマップの左境界に変換されます。このため、このポイントのビットマップ座標の x 値は 0 に等しく、否定されます (x-値は正である必要があります) 変換された座標の x 値は、シフトの x 値です。結果のビットマップの左境界に変換されるポイントは、最大の否定された x 値を持つポイントです。したがって、シフトの x 値は、変換された左上点と左下点の否定された x 値の最大値です。
y 値を計算するために、元の画像の左上の点の y 値と右上の点の y 値を変換しました。これは、結果の上部境界に変換される可能性のある点であるためです。変換されたポイントの y 値は、結果のビットマップでは 0 に等しくなります。変換された y 値の否定された値の最大値を再度取得することにより、シフトの y 値を取得します。
結果のコードは次のようになります。
float[] mappedTL = new float[] { 0, 0 };
matrix.mapPoints(mappedTL);
int maptlx = Math.round(mappedTL[0]);
int maptly = Math.round(mappedTL[1]);
float[] mappedTR = new float[] { bitmap.getWidth(), 0 };
matrix.mapPoints(mappedTR);
int maptrx = Math.round(mappedTR[0]);
int maptry = Math.round(mappedTR[1]);
float[] mappedLL = new float[] { 0, bitmap.getHeight() };
matrix.mapPoints(mappedLL);
int mapllx = Math.round(mappedLL[0]);
int maplly = Math.round(mappedLL[1]);
int shiftX = Math.max(-maptlx, -mapllx);
int shiftY = Math.max(-maptry, -maptly);
Bitmap resultBitmap = Bitmap.createBitmap(bitmap, 0, 0, bitmap.getWidth(), bitmap.getHeight(), matrix, true);
return Bitmap.createBitmap(resultBitmap, shiftX, shiftY, bitmap.getWidth(), bitmap.getHeight(), null, true);