Distorting eines Bildes zu einem Viereck scheitern Ich verwende Matrix.setPolyToPoly Funktion, um eine ausgewählte Region (4 Ecken) einer Bitmap in ein Rechteck zu transformieren und normalerweise funktioniert es erstaunlich. Aber im nächsten Beispiel:In einigen Fällen auf Android
Die polyToPoly Funktion schlägt die perspektivische Transformation:
ich gezeichnet haben zwei Linien für die Prüfung, markieren Sie die Zeilen, in denen ich die vier ausgewählten Punkten wollen .
Was mache ich falsch? Vielen Dank!
EDIT: Ich habe das Problem mit canvas.drawBitmapMesh gelöst haben, Dank pskink für Ihre Beratung !!
Dies ist der letzte Code
private float[] generateVertices(int widthBitmap, int heightBitmap) {
float[] vertices=new float[(WIDTH_BLOCK+1)*(HEIGHT_BLOCK+1)*2];
float widthBlock = (float)widthBitmap/WIDTH_BLOCK;
float heightBlock = (float)heightBitmap/HEIGHT_BLOCK;
for(int i=0;i<=HEIGHT_BLOCK;i++)
for(int j=0;j<=WIDTH_BLOCK;j++) {
vertices[i * ((HEIGHT_BLOCK+1)*2) + (j*2)] = j * widthBlock;
vertices[i * ((HEIGHT_BLOCK+1)*2) + (j*2)+1] = i * heightBlock;
}
return vertices;
}
private Bitmap perspectiveTransformation(Bitmap bitmap, ArrayList<Point> bitmapPoints) {
Bitmap correctedBitmap;
int maxX = (int) Math.max(Math.abs(bitmapPoints.get(0).x - bitmapPoints.get(1).x), Math.abs(bitmapPoints.get(2).x - bitmapPoints.get(3).x));
int maxY = (int) Math.max(Math.abs(bitmapPoints.get(0).y - bitmapPoints.get(3).y), Math.abs(bitmapPoints.get(1).y - bitmapPoints.get(2).y));
Log.d("max", "x=" + maxX + " y=" + maxY); //This is the desired final size
Bitmap.Config conf = Bitmap.Config.ARGB_8888;
correctedBitmap = Bitmap.createBitmap(maxX,maxY,conf); //the final bitmap
float mVertices[] =generateVertices(bitmap.getWidth(),bitmap.getHeight());
Point mLeftTop = bitmapPoints.get(0);
Point mRightTop = bitmapPoints.get(1);
Point mLeftBot = bitmapPoints.get(3);
Point mRightBot = bitmapPoints.get(2); //the points on the image where the user has clicked
Canvas canvas = new Canvas(correctedBitmap);
Matrix matrix = new Matrix();
matrix.setPolyToPoly(
new float[]{mLeftTop.x, mLeftTop.y,
mRightTop.x, mRightTop.y,
mRightBot.x, mRightBot.y,
mLeftBot.x, mLeftBot.y //the user's points
},
0,
new float[]{0, 0,
maxX - 1, 0,
maxX - 1, maxY - 1,
0, maxY - 1 //where I want the user points in the corrected image
}
, 0, 4);
canvas.concat(matrix);
Paint paint = new Paint();
paint.setAntiAlias(true); //testing parameters
paint.setFilterBitmap(true); //testing parameters
paint.setColor(Color.BLUE);
paint.setStyle(Paint.Style.STROKE);
canvas.drawBitmapMesh(bitmap, WIDTH_BLOCK , HEIGHT_BLOCK, mVertices,0,null,0, paint); //draw the original bitmap into the corrected bitmap with PolyToPoly transformation matrix
canvas.drawLine(mLeftTop.x, mLeftTop.y, mRightBot.x, mRightBot.y, paint); //draw two lines for testing the transformation matrix
canvas.drawLine(mLeftBot.x, mLeftBot.y, mRightTop.x, mRightTop.y, paint);
//bitmap.recycle(); //just testing
return correctedBitmap;
}
man kann nicht alles tun mit 'setPolyToPoly', versuchen' Canvas.drawBitmapMesh' statt – pskink
Dank! Ich habe die Frage mit dem endgültigen Code aktualisiert. –
@PepSantacruz Vielen Dank für eine klare, gut ausgedrückte Frage. Der Sinn von SO ist, dass Fragen und Antworten auch nach dem ursprünglichen Beitrag für andere hilfreich sein können. Könnten Sie die Bearbeitung auf Ihre Frage zurücksetzen, so dass der Code dem des ursprünglichen Posts entspricht (mit dem funktionierenden Code in der Antwort, wie Sie es getan haben)? Könnten Sie Ihre Antwort auch "akzeptieren"? Dadurch können künftige Besucher einen klaren Unterschied zwischen dem Code, der ein Problem hatte, und dem Code, der das Problem behoben hat, erkennen. "Akzeptieren" wird einen offensichtlichen Hinweis darauf geben, dass diese Antwort das Problem behoben hat. – Gary99