I am developing an application that has a function that resizes and rotates an image by dragging its button in the lower right corner.
I saw one application that has a function that, if we drag the button of the lower right corner diagonally, reduce the size of the image, or if we drag the button left or right, the image was viewed in the direction. I want to implement this function in my application
I'm struggling to implement a single rotation of the finger, as well as resize the image.
Please guide me correctly. 
I am trying to use this code and trying to apply scaling and rotation, but I am not able to do it, please help me. clear the code to zoom in and rotate the action of the finger base.
public class ScaleActivity extends Activity { ViewGroup lLayout; static ImageView img, backgrndImg; Canvas mCanvas; float d; private float mAspectQuotient; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); lLayout = (FrameLayout) findViewById(R.id.lLayout); final CropView cv = new CropView(this); lLayout.addView(cv); } @Override public boolean onCreateOptionsMenu(Menu menu) { // Inflate the menu; this adds items to the action bar if it is present. getMenuInflater().inflate(R.menu.main, menu); return true; } public class CropView extends ImageView { private static final int SELECTION_RECT_PAINT_COLOR = 0xFF000000; private static final int SELECTION_RECT_FILL_COLOR = 0x70FFFFFF; private static final int TOUCH_TOLERANCE = 25; private static final int xInc = 25; private static final int yInc = 25; Paint paint = new Paint(); private int initial_size = 200; private Point leftTop, rightBottom, center, previous, currentPoint, rectPos; private Paint fillPaint; private Paint rectPaint; protected Rect selection, dest; private boolean isAffectedBottom = false; Bitmap bitmap, backgroundBitmap; Rect rectf; Rect knobRect; private Context mContext; int width, height; private Matrix matrix = new Matrix(); Bitmap resizedBitmap; // Adding parent class constructors public CropView(Context context) { super(context); mContext = context; backgroundBitmap = BitmapFactory.decodeResource(getContext() .getResources(), R.drawable.toast_bkgrd); bitmap = BitmapFactory.decodeResource(getContext().getResources(), R.drawable.aviary_adjust_knob); rectPaint = new Paint(); rectPaint.setStyle(Style.STROKE); rectPaint.setColor(SELECTION_RECT_PAINT_COLOR); fillPaint = new Paint(); fillPaint.setStyle(Style.FILL); fillPaint.setColor(SELECTION_RECT_FILL_COLOR); currentPoint = new Point(getWidth() / 2, getHeight() / 2); width = backgroundBitmap.getWidth(); height = backgroundBitmap.getHeight(); initCropView(); } public CropView(Context context, AttributeSet attrs) { super(context, attrs, 0); initCropView(); } public CropView(Context context, AttributeSet attrs, int defStyle) { super(context, attrs, defStyle); initCropView(); } @SuppressLint("DrawAllocation") @Override protected void onDraw(Canvas canvas) { super.onDraw(canvas); mCanvas = canvas; if (leftTop.equals(0, 0)) resetPoints(); mCanvas.save(); resizedBitmap = Bitmap.createBitmap(backgroundBitmap, 0, 0, backgroundBitmap.getWidth(), backgroundBitmap.getHeight(), matrix, true); // mCanvas.drawBitmap(backgroundBitmap, matrix, rectPaint); mCanvas.drawBitmap(resizedBitmap, null, selection, rectPaint); mCanvas.drawBitmap(bitmap, selection.right - 25, selection.bottom - 25, null); rectPos.set(selection.left, selection.top); mCanvas.restore(); } @Override public boolean onTouchEvent(MotionEvent event) { int eventaction = event.getAction(); switch (eventaction) { case MotionEvent.ACTION_DOWN: touchDown((int) event.getX(), (int) event.getY()); previous.set((int) event.getX(), (int) event.getY()); break; case MotionEvent.ACTION_MOVE: touchMove((int) event.getX(), (int) event.getY()); if (isActionInsideRectangle(event.getX(), event.getY()) && !isAffectedBottom) { drag((int) event.getX(), (int) event.getY()); invalidate(); // redraw rectangle previous.set((int) event.getX(), (int) event.getY()); } previous.set((int) event.getX(), (int) event.getY()); break; case MotionEvent.ACTION_UP: touchUp((int) event.getX(), (int) event.getY()); previous = new Point(); break; } return true; } private void initCropView() { paint.setColor(Color.WHITE); paint.setStyle(Style.STROKE); paint.setStrokeWidth(5); leftTop = new Point(); rightBottom = new Point(); center = new Point(); previous = new Point(); rectPos = new Point(); } public void resetPoints() { center.set(getWidth() / 2, getHeight() / 2); leftTop.set((getWidth() - initial_size) / 2, (getHeight() - initial_size) / 2); rightBottom.set(leftTop.x + initial_size, leftTop.y + initial_size); selection = new Rect(leftTop.x, leftTop.y, rightBottom.x, rightBottom.y); knobRect = new Rect(selection.right, selection.bottom, bitmap.getWidth(), bitmap.getHeight()); dest = selection; } private boolean isActionInsideRectangle(float x, float y) { int buffer = 10; return (x >= (selection.left) && x <= (selection.right) && y >= (selection.top) && y <= (selection.bottom)) ? true : false; } void touchDown(int x, int y) { System.out.println("selection " + selection); int dx = (previous.x - x) / 2; int dy = (previous.y - y) / 2; // d= rotation(dx,dy); currentPoint.set(x, y); if (pointsAreClose(x, y, selection.right, selection.bottom)) { isAffectedBottom = true; System.out.println("isAffectedBottom " + isAffectedBottom); } } void touchMove(int x, int y) { currentPoint.set(x, y); if (isAffectedBottom) { int dx = (previous.x - x) / 2; int dy = (previous.y - y) / 2; double startAngle = getAngle(previous.x, previous.y); double currentAngle = getAngle(x, y); matrix.postRotate((float) (startAngle - currentAngle), selection.width() / 2.0f, selection.height() / 2.0f); // selection.inset(dx, dy); invalidate(); } } void touchUp(int x, int y) { currentPoint.set(x, y); isAffectedBottom = false; } private boolean pointsAreClose(float x1, float y1, float x2, float y2) { return Math.hypot(x1 - x2, y1 - y2) < TOUCH_TOLERANCE; } private void drag(int x, int y) { int movement; movement = x - previous.x; int movementY = y - previous.y; selection.set(selection.left + movement, selection.top + movementY, selection.right + movement, selection.bottom + movementY); selection.sort(); invalidate(); } /** * Calculate the degree to be rotated by. * * @param event * @return Degrees */ // private float rotation(float dx, float dy) { // // // double delta_x = (dx); // // double delta_y = (dy); // double radians = Math.atan2((selection.left) - (previous.y), // (selection.top) - (previous.x)); // double radians2 = Math.atan2((selection.left) - (dy), // (selection.top) - (dx)); // // System.out.println("radians" + radians); // System.out.println("" + radians2); // System.out.println("radians2-radians" + (radians2 - radians)); // System.out.println(Math.toDegrees(radians2 - radians)); // return (float) Math.toDegrees(radians2 - radians); // // } private double getAngle(double xTouch, double yTouch) { double x = xTouch - (getWidth() / 2d); double y = getHeight() - yTouch - (getHeight() / 2d); switch (getQuadrant(x, y)) { case 1: System.out.println("1"); return Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI; case 2: case 3: System.out.println("32"); return 180 - (Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI); case 4: System.out.println("4"); return 360 + Math.asin(y / Math.hypot(x, y)) * 180 / Math.PI; default: // ignore, does not happen return 0; } } /** * @return The selected quadrant. */ private int getQuadrant(double x, double y) { if (x >= 0) { return y >= 0 ? 1 : 4; } else { return y >= 0 ? 2 : 3; } } } }