Zoom کردن عکس با استفاده از view در اندروید
یکشنبه 24 آبان 1394در این مقاله می خواهیم با استفاده از 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); } }
خروجی کار به صورت زیر است:
- Android
- 3k بازدید
- 1 تشکر