آموزش zoom کردن عکس در برنامه نویسی اندروید
سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش zoom کردن عکس در برنامه نویسی اندروید می پردازیم دلیل zoom کردن به روشنی معلوم است و در ادامه با ما همراه باشید تا نحوه استفاده از آن را یاد بگیرد.
ابتدا شما باید یک کلاس به نام TouchImageView.java ایجاد کرده تا انجام کارهایی مثل zoom کردن یا zoom-in و بیرون آمدن از zoom یا zoom-out را handle کند و زمانی که کاربر بروی عکس دوبار کلیک کرد عکس zoom-out شود
package ir.programchi;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.util.AttributeSet;
import android.view.GestureDetector;
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;
float redundantXSpace, redundantYSpace, origRedundantXSpace, origRedundantYSpace;
int viewWidth, viewHeight;
static final int CLICK = 3;
static final float SAVE_SCALE = 1f;
float saveScale = SAVE_SCALE;
protected float origWidth, origHeight;
int oldMeasuredWidth, oldMeasuredHeight;
float origScale, bottom, origBottom, right, origRight;
ScaleGestureDetector mScaleDetector;
GestureDetector mGestureDetector;
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) {
boolean onDoubleTapEvent = mGestureDetector.onTouchEvent(event);
if (onDoubleTapEvent) {
// Reset Image to original scale values
mode = NONE;
bottom = origBottom;
right = origRight;
last = new PointF();
start = new PointF();
m = new float[9];
saveScale = SAVE_SCALE;
matrix = new Matrix();
matrix.setScale(origScale, origScale);
matrix.postTranslate(origRedundantXSpace, origRedundantYSpace);
setImageMatrix(matrix);
invalidate();
return true;
}
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
}
});
mGestureDetector = new GestureDetector(context, new GestureDetector.SimpleOnGestureListener() {
@Override
public boolean onDoubleTapEvent(MotionEvent e) {
return true;
}
});
}
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 mScaleFactor = (float) Math.min(Math.max(.95f, detector.getScaleFactor()), 1.05);
float origScale = saveScale;
saveScale *= mScaleFactor;
if (saveScale > maxScale) {
saveScale = maxScale;
mScaleFactor = maxScale / origScale;
} else if (saveScale < minScale) {
saveScale = minScale;
mScaleFactor = minScale / origScale;
}
right = viewWidth * saveScale - viewWidth - (2 * redundantXSpace * saveScale);
bottom = viewHeight * saveScale - viewHeight - (2 * redundantYSpace * saveScale);
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;
int bmWidth,bmHeight;
Bitmap bm = BitmapFactory.decodeResource(context.getResources(), R.mipmap.myinfolinks_splash);
bmWidth = bm.getWidth();
bmHeight = bm.getHeight();
int w = bmWidth;
int h = bmHeight;
viewWidth = resolveSize(w, widthMeasureSpec);
viewHeight = resolveSize(h, heightMeasureSpec);
float scaleX = (float) viewWidth / (float) bmWidth;
float scaleY = (float) viewHeight / (float) bmHeight;
scale = Math.min(scaleX, scaleY);
matrix.setScale(scale, scale);
saveScale = SAVE_SCALE;
origScale = scale;
// Center the image
redundantYSpace = (float) viewHeight - (scale * (float) bmHeight);
redundantXSpace = (float) viewWidth - (scale * (float) bmWidth);
redundantYSpace /= (float) 2;
redundantXSpace /= (float) 2;
origRedundantXSpace = redundantXSpace;
origRedundantYSpace = redundantYSpace;
matrix.postTranslate(redundantXSpace, redundantYSpace);
origWidth = viewWidth - 2 * redundantXSpace;
origHeight = viewHeight - 2 * redundantYSpace;
right = viewWidth * saveScale - viewWidth - (2 * redundantXSpace * saveScale);
bottom = viewHeight * saveScale - viewHeight - (2 * redundantYSpace * saveScale);
origRight = right;
origBottom = bottom;
setImageMatrix(matrix);
}
fixTrans();
}
}
این کلاس بسیار پیچیده است و محسابات بسیار سنگینی دارد در بالا ما از Gesture برای handle کردن انواع touch استفاده کردیم یعنی زمانی که با دو انگشت خود بروی عکس رفت باعث زوم شدن شود و زمانی که دوبار پشت سر هم بروی عکس کلیک کند zoom out خواهد شد
ابتدا وارد layout خود شده کد زیر را قرار دهید.
<ir.programchi.TouchImageView
android:id="@+id/action_infolinks_splash"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:src="@mipmap/myinfolinks_splash"
android:layout_gravity="center"
android:gravity="center"
android:scaleType="fitCenter"/>
حالا نحوه استفاده از آن به شکل زیر می شود وارد اکتیویتی خود شده و کد زیر را قرار دهید.
TouchImageView imgDisplay = (TouchImageView) messageView.findViewById(R.id.id_myImage); imgDisplay.setMaxZoom(2f); imgDisplay.setImageResource(R.drawable.myImage);
به این شکل می توانید استفاده کنید.
این آموزش هم به پایان رسید.
موفق باشید.
آموزش برنامه نویسی اندروید |
سلام
باتشکر بابت سایت بسیار خوبت
بیزحمت در هر اموزش کدها رو هم توضیح بدید
اینجوری درک مطلب بهتر میشه
انشاالله بهتر توضیح خواهیم داد.
موفق و موید باشید.
()setImageMatrix این کجا تعریف شده؟؟؟
از توابع کلاس imageview می باشد
سلام وقتی اضافه میکنم کد رو image view ارور میده
public class TouchImageView extends ImageView
logcat لطفا
سلام آموزشتون خوبه فقط من یه مشکلی دارم اونم اینه که شما تو اخرین کدی که نوشتید یک ایمیح رو گزاشتین که هرچی که ما تایین بکنیم رو همون زوم میکنه اما من میخوام اینو رو یه Imageview پیاده کنم یعنی اون ایمیج ویو رو زوم کنه این رو باید چیکار کنم؟؟؟؟؟؟
باسلام ، ببخشید مهندس چجوری میشه روی یک View دیگه (مثلا: Layout) زوم کرد؟
آره واقعا سوال من هم هست لطفا جواب بدید