0

I am able to zoom and drag an image in android but not to rotate it. With the following code I am able to do this.I want to rotate in both directions i.e. clockwise as well as anti-clockwise. With the following code I am able to do this.

I hope to be clear.

ZoomableImageView

 public class ZoomableImageView extends ImageView {


    static final int NONE = 0;
    static final int DRAG = 1;
    static final int ZOOM = 2;
    static final int CLICK = 3;
    private static final String TAG = "ZoomableImageView";
    float[] lastEvent = null;
    float d = 0f;
    float newRot = 0f;
    private float r;
    private int mode = NONE;
    private Matrix matrix = new Matrix();
    private PointF last = new PointF();
    private PointF start = new PointF();
    private float minScale = 0.1f;
    private float maxScale = 4f;
    private float[] m;
    private float redundantXSpace, redundantYSpace;
    private float saveScale = 1f;
    private float right, bottom, originalBitmapWidth, originalBitmapHeight;
    private ScaleGestureDetector mScaleDetector;

    public ZoomableImageView(Context context) {
        super(context);
        init(context);
    }

    public ZoomableImageView(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context);
    }

    public ZoomableImageView(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
        init(context);
    }

    private void init(Context context) {
        super.setClickable(true);
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());
        m = new float[9];
        setImageMatrix(matrix);
        setScaleType(ScaleType.MATRIX);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        int bmHeight = getBmHeight();
        int bmWidth = getBmWidth();

        float width = getMeasuredWidth();
        float height = getMeasuredHeight();
        //Fit to screen.
        float scale = width > height ? height / bmHeight : width / bmWidth;

        matrix.setScale(scale, scale);
        saveScale = 1f;

        originalBitmapWidth = scale * bmWidth;
        originalBitmapHeight = scale * bmHeight;

        // Center the image
        redundantYSpace = (height - originalBitmapHeight);
        redundantXSpace = (width - originalBitmapWidth);

        matrix.postTranslate(redundantXSpace / 2, redundantYSpace / 2);

        setImageMatrix(matrix);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        mScaleDetector.onTouchEvent(event);

        matrix.getValues(m);
        float x = m[Matrix.MTRANS_X];
        float y = m[Matrix.MTRANS_Y];
        PointF curr = new PointF(event.getX(), event.getY());

        switch (event.getAction()) {
            //when one finger is touching
            //set the mode to DRAG
            case MotionEvent.ACTION_DOWN:
                last.set(event.getX(), event.getY());
                start.set(last);
                mode = DRAG;
                lastEvent = null;
                break;
            //when two fingers are touching
            //set the mode to ZOOM
            case MotionEvent.ACTION_POINTER_DOWN:
                last.set(event.getX(), event.getY());
                start.set(last);
                mode = ZOOM;
                lastEvent = new float[4];
                lastEvent[0] = event.getX(0);
                lastEvent[1] = event.getX(1);
                lastEvent[2] = event.getY(0);
                lastEvent[3] = event.getY(1);
                d = rotation(event);
                break;
            //when a finger moves
            //If mode is applicable move image
            case MotionEvent.ACTION_MOVE:
                //if the mode is ZOOM or
                //if the mode is DRAG and already zoomed
                if (mode == ZOOM || (mode == DRAG && saveScale > minScale)) {
                    float deltaX = curr.x - last.x;// x difference
                    float deltaY = curr.y - last.y;// y difference
                    //move the image with the matrix
                    matrix.postTranslate(deltaX, deltaY);}

                if (lastEvent != null) {
                    newRot = rotation(event);
                    float r = newRot - d;
                    matrix.postRotate(r, getMeasuredWidth() / 2,
                            getMeasuredHeight() / 2);
                }
                    //set the last touch location to the current
                    last.set(curr.x, curr.y);
                break;
            //first finger is lifted
            case MotionEvent.ACTION_UP:
                mode = NONE;
                int xDiff = (int) Math.abs(curr.x - start.x);
                int yDiff = (int) Math.abs(curr.y - start.y);
                if (xDiff < CLICK && yDiff < CLICK)
                    performClick();
                break;
            // second finger is lifted
            case MotionEvent.ACTION_POINTER_UP:
                mode = NONE;
                lastEvent = null;
                break;
        }
        setImageMatrix(matrix);
        invalidate();
        return true;
    }

    public void setMaxZoom(float x) {
        maxScale = x;
    }

    private int getBmWidth() {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            return drawable.getIntrinsicWidth();
        }
        return 0;
    }

    private int getBmHeight() {
        Drawable drawable = getDrawable();
        if (drawable != null) {
            return drawable.getIntrinsicHeight();
        }
        return 0;
    }

    private float rotation(MotionEvent event) {
        double delta_x = (event.getX(0) - event.getX(1));
        double delta_y = (event.getY(0) - event.getY(1));
        double radians = Math.atan2(delta_y, delta_x);
        return (float) Math.toDegrees(radians);
    }

    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {

        @Override
        public boolean onScaleBegin(ScaleGestureDetector detector) {
            mode = ZOOM;
            return true;
        }

        @Override
        public boolean onScale(ScaleGestureDetector detector) {
            float scaleFactor = detector.getScaleFactor();
            float newScale = saveScale * scaleFactor;
            if (newScale < maxScale && newScale > minScale) {
                saveScale = newScale;
                float width = getWidth();
                float height = getHeight();
                right = (originalBitmapWidth * saveScale) - width;
                bottom = (originalBitmapHeight * saveScale) - height;
                float scaledBitmapWidth = originalBitmapWidth * saveScale;
                float scaledBitmapHeight = originalBitmapHeight * saveScale;
                if (scaledBitmapWidth <= width || scaledBitmapHeight <= height) {
                    matrix.postScale(scaleFactor, scaleFactor, width / 2, height / 2);
                } else {
                    matrix.postScale(scaleFactor, scaleFactor, detector.getFocusX(), detector.getFocusY());
                }
            }
            return true;
        }

    }
}
Deepak Sachdeva
  • 950
  • 8
  • 16
Harmeet Kaur
  • 154
  • 14
  • Refer this link. It may help you. http://stackoverflow.com/questions/8981845/android-rotate-image-in-imageview-by-an-angle – ajantha Dec 14 '16 at 06:23

2 Answers2

0

Try this to rotate a image.

@Override
public boolean onTouch(View v, MotionEvent event) {
    final float xc = imgView.getWidth() / 2;
    final float yc = imgView.getHeight() / 2;

    final float x = event.getX();
    final float y = event.getY();

    switch (event.getAction()) {
    case MotionEvent.ACTION_DOWN: {
        imgView.clearAnimation();
        mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
        break;
    }
    case MotionEvent.ACTION_MOVE: {
        mPrevAngle = mCurrAngle;
        mCurrAngle = Math.toDegrees(Math.atan2(x - xc, yc - y));
        animate(mPrevAngle, mCurrAngle, 0);
        break;
    }
    case MotionEvent.ACTION_UP : {
        mPrevAngle = mCurrAngle = 0;
        break;
    }
    }

    return true;
}

private void animate(double fromDegrees, double toDegrees, long durationMillis) {
    final RotateAnimation rotate = new RotateAnimation((float) fromDegrees, (float) toDegrees,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f,
            RotateAnimation.RELATIVE_TO_SELF, 0.5f);
    rotate.setDuration(durationMillis);
    rotate.setFillEnabled(true);
    rotate.setFillAfter(true);
    imgView.startAnimation(rotate);
}
Deepak Sachdeva
  • 950
  • 8
  • 16
0
 float degree = Math.round(sensorEvent.values[0]);
        tvHeading.setText(Float.toString(degree) + " degrees");
        RotateAnimation ra = new RotateAnimation(
                of, -degree,
                Animation.RELATIVE_TO_SELF, 0.5f,
                Animation.RELATIVE_TO_SELF,
                0.5f);
        // how long the animation will take place
        ra.setDuration(210);
        // set the animation after the end of the reservation status
        ra.setFillAfter(true);
        // Start the animation
        image.startAnimation(ra);

//change the degree acc to your need

Vikas Rana
  • 26
  • 7