An answer was found based on this post .
It seems that the Matrix cannot be used because it cannot create Trapezoid shapes that can occur in the 3D world.
So, it is suggested to use the Camera class:
Canvas canvas = new Canvas(bigBitmap); Matrix matrix = new Matrix(); Camera camera = new Camera(); camera.save(); camera.translate(...,...,0); camera.rotateX(...); camera.rotateY(...); camera.rotateZ(...); camera.getMatrix(matrix); int centerX = bigBitmap.getWidth() / 2; int centerY = bigBitmap.getHeight() / 2; matrix.preTranslate(-centerX, -centerY);
Unfortunately, as you can see, the coordinates are not used, so you need to either play with the numbers until it works out, or find a formula for converting between the coordinates and the necessary values.
I will not mark this answer as correct, because it does not fully meet the requirements of the original question (no coordinates are used).
Plus, I canβt find how to work with text when using this solution.
However, it works, so it can be useful to others.
EDIT: It seems that the reason setPolyToPoly doesn't scale the image at all is because the first input array was wrong: it was set as the size of a large bitmap, not a small one.
So this is the correct code:
mLeftTop = new Point(370, 358); mRightTop = new Point(650, 384); mLeftBot = new Point(375, 972); mRightBot = new Point(660, 942); Canvas canvas = new Canvas(mBigBitmap); final Matrix matrix = new Matrix(); matrix.setPolyToPoly(new float[]{0, 0, mSmallBitmap.getWidth() - 1, 0, 0, mSmallBitmap.getHeight() - 1, mSmallBitmap.getWidth() - 1, mSmallBitmap.getHeight() - 1}, 0, new float[]{mLeftTop.x, mLeftTop.y, mRightTop.x, mRightTop.y, mLeftBot.x, mLeftBot.y, mRightBot.x, mRightBot.y } , 0, 4); canvas.concat(matrix); final Paint paint = new Paint(); paint.setAntiAlias(true); canvas.drawBitmap(mSmallBitmap, 0, 0, paint);
However, there is still this problem for center cropping, but if you know the correct size of the rectangle before it is tilted, you can crop it earlier and set it as input.
As for the text, this is possible, as usual, since the canvas remains with the created matrix.