Zoom کردن عکس با استفاده از view در اندروید

یکشنبه 24 آبان 1394

در این مقاله می خواهیم با استفاده از view یک عکسی را که در صفحه داریم بتوانیم آن را با لمس کردن صفحه ی گوشی بزرگ یا کوچک نماییم.

Zoom کردن عکس با استفاده از view در اندروید

Zoom کردن تصویر قابلیت های بسیار بالایی دارد به طوری که شما می توانید یک تصویر را که خیلی بزرگ است با دو انگشت خود آن را بزرگ یا کوچک نمایید.

حتما تا به حال در گالری تصاویر خود دیده باشید که وقتی یک عکسی را در صفحه قرار دارد می توانید آن را بزرگ یا کوچیک نمایید.

قدم اول یک پروژه ی جدید ایجاد نمایید.

از کلاس TouchImageView برای بزرگ نمایی عکس و لمس کردن آن و اینکه موقعیت عکس بعد از کوچک و بزرگ کردن آن در کجا قرار گیرد.

import android.content.Context;  
import android.graphics.Matrix;  
import android.graphics.PointF;  
import android.graphics.drawable.Drawable;  
import android.util.AttributeSet;  
import android.util.Log;  
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;  
import android.view.View;  
import android.widget.ImageView;  
 
public class TouchImageView extends ImageView {  
    Matrix matrix;  
    // We can be in one of these 3 states  
    static final int NONE = 0;  
    static final int DRAG = 1;  
    static final int ZOOM = 2;  
  
    int mode = NONE;  
 
    // Remember some things for zooming  
    PointF last = new PointF();  
    PointF start = new PointF();  
    float minScale = 1f;  
    float maxScale = 3f;  
    float[] m;
    int viewWidth, viewHeight;  
  
    static final int CLICK = 3;  
  
    float saveScale = 1f;  
  
    protected float origWidth, origHeight;  
  
    int oldMeasuredWidth, oldMeasuredHeight;  
 
    ScaleGestureDetector mScaleDetector;  
 
    Context context;  
 
    public TouchImageView(Context context) {  
        super(context);  
        sharedConstructing(context);  
    } 

    public TouchImageView(Context context, AttributeSet attrs) {  
        super(context, attrs);  
        sharedConstructing(context);  
    }  
  
    private void sharedConstructing(Context context) {  
  
        super.setClickable(true);  
  
        this.context = context;  
  
        mScaleDetector = new ScaleGestureDetector(context, new ScaleListener());  
  
        matrix = new Matrix();  
  
        m = new float[9];  
  
        setImageMatrix(matrix);  
  
        setScaleType(ScaleType.MATRIX);  
 
        setOnTouchListener(new OnTouchListener() {  
 
            @Override  
            public boolean onTouch(View v, MotionEvent event) {  
  
                mScaleDetector.onTouchEvent(event);  
  
                PointF curr = new PointF(event.getX(), event.getY());  
  
                switch (event.getAction()) {  
  
                    case MotionEvent.ACTION_DOWN:  
  
                       last.set(curr);  
  
                        start.set(last);  
  
                        mode = DRAG;  
  
                        break;  
 
                    case MotionEvent.ACTION_MOVE:  
  
                        if (mode == DRAG) {  
  
                            float deltaX = curr.x - last.x;  
  
                            float deltaY = curr.y - last.y;  
  
                            float fixTransX = getFixDragTrans(deltaX, viewWidth, origWidth * saveScale);  
  
                            float fixTransY = getFixDragTrans(deltaY, viewHeight, origHeight * saveScale);  
  
                            matrix.postTranslate(fixTransX, fixTransY);  
  
                            fixTrans();  
  
                            last.set(curr.x, curr.y);  
  
                        }  
  
                        break;  
  
                    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;  
  
                    case MotionEvent.ACTION_POINTER_UP:  
  
                        mode = NONE;  
  
                        break;  
  
                }  
  
                setImageMatrix(matrix);  
  
                invalidate();  
  
                return true; // indicate event was handled  
  
            }  
 
        });
    }  
  
    public void setMaxZoom(float x) {  
  
        maxScale = x;  
  
    }  
  
    private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {  
  
        @Override  
        public boolean onScaleBegin(ScaleGestureDetector detector) {  
  
            mode = ZOOM;  
  
            return true;  
  
        }  

        @Override  
        public boolean onScale(ScaleGestureDetector detector) {  
  
            float mScaleFactor = detector.getScaleFactor();  
  
            float origScale = saveScale;  
  
            saveScale *= mScaleFactor;  
  
            if (saveScale > maxScale) {  
  
                saveScale = maxScale;  
  
                mScaleFactor = maxScale / origScale;  
  
            } else if (saveScale < minScale) {  
  
                saveScale = minScale;  
  
                mScaleFactor = minScale / origScale;  
  
            }  
 
            if (origWidth * saveScale <= viewWidth || origHeight * saveScale <= viewHeight)  
  
                matrix.postScale(mScaleFactor, mScaleFactor, viewWidth / 2, viewHeight / 2);  
  
            else  
  
                matrix.postScale(mScaleFactor, mScaleFactor, detector.getFocusX(), detector.getFocusY());  
  
            fixTrans();  
  
            return true;  
  
        }  
  
    }  
  
    void fixTrans() {  
  
        matrix.getValues(m);  
  
        float transX = m[Matrix.MTRANS_X];  
  
        float transY = m[Matrix.MTRANS_Y];  
  
        float fixTransX = getFixTrans(transX, viewWidth, origWidth * saveScale);  
  
        float fixTransY = getFixTrans(transY, viewHeight, origHeight * saveScale);  
  
        if (fixTransX != 0 || fixTransY != 0)  
  
            matrix.postTranslate(fixTransX, fixTransY);  
  
    }  
  
   
  
    float getFixTrans(float trans, float viewSize, float contentSize) {  
  
        float minTrans, maxTrans;  
  
        if (contentSize <= viewSize) {  
  
            minTrans = 0;  
  
            maxTrans = viewSize - contentSize;  
  
        } else {  
  
            minTrans = viewSize - contentSize;  
  
            maxTrans = 0;  
  
        }  
  
        if (trans < minTrans)  
  
            return -trans + minTrans;  
  
        if (trans > maxTrans)  
  
            return -trans + maxTrans;  
  
        return 0;  
  
    }  
 
    float getFixDragTrans(float delta, float viewSize, float contentSize) {  
  
        if (contentSize <= viewSize) {  
  
            return 0;  
  
        }  
  
        return delta;  
  
    }  
  
    @Override  
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {  
  
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);  
  
        viewWidth = MeasureSpec.getSize(widthMeasureSpec);  
  
        viewHeight = MeasureSpec.getSize(heightMeasureSpec);  
  
        //  
        // Rescales image on rotation  
        //  
        if (oldMeasuredHeight == viewWidth && oldMeasuredHeight == viewHeight  
  
                || viewWidth == 0 || viewHeight == 0)  
  
            return;  
  
        oldMeasuredHeight = viewHeight;  
  
        oldMeasuredWidth = viewWidth;
  
        if (saveScale == 1) {  
  
            //Fit to screen.  
  
            float scale;  
  
            Drawable drawable = getDrawable();  
  
            if (drawable == null || drawable.getIntrinsicWidth() == 0 || drawable.getIntrinsicHeight() == 0)  
  
                return;  
  
            int bmWidth = drawable.getIntrinsicWidth();  
  
            int bmHeight = drawable.getIntrinsicHeight();  
  
            Log.d("bmSize", "bmWidth: " + bmWidth + " bmHeight : " + bmHeight);  
  
            float scaleX = (float) viewWidth / (float) bmWidth;  
  
            float scaleY = (float) viewHeight / (float) bmHeight;  
  
            scale = Math.min(scaleX, scaleY);  
  
            matrix.setScale(scale, scale);  
  
            // Center the image  
  
            float redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);  
  
            float redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);  
  
            redundantYSpace /= (float) 2;  
  
            redundantXSpace /= (float) 2;  
  
            matrix.postTranslate(redundantXSpace, redundantYSpace);  
  
            origWidth = viewWidth - 2 * redundantXSpace;  
  
            origHeight = viewHeight - 2 * redundantYSpace;  
  
            setImageMatrix(matrix);  
  
        }  
  
        fixTrans();  
  
    }  
  
}  

ما از یک Imageview استفاده می کنیم و ویژگی های آن را در کد قرار می دهیم.

ما activity اصلی را باز می کنیم، و کد زیر را وارد می کنیم.

import android.os.Bundle;  
import android.app.Activity;  
import android.view.Menu;  
  
public class MultiTouchActivity extends Activity {  
    @Override  
    protected void onCreate(Bundle savedInstanceState) {  
        super.onCreate(savedInstanceState);  
        //setContentView(R.layout.activity_main);  
  
        TouchImageView img = new TouchImageView(this);  
        img.setImageResource(R.drawable.ice_age_2);  
        img.setMaxZoom(4f);  
        setContentView(img);  
    }  
}  

خروجی کار به صورت زیر است:

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید