آموزش zoom کردن عکس در برنامه نویسی اندروید
سلام دوستان در این سری از آموزش برنامه نویسی اندروید به آموزش zoom کردن عکس در برنامه نویسی اندروید می پردازیم دلیل zoom کردن به روشنی معلوم است و در ادامه با ما همراه باشید تا نحوه استفاده از آن را یاد بگیرد.
ابتدا شما باید یک کلاس به نام TouchImageView.java ایجاد کرده تا انجام کارهایی مثل zoom کردن یا zoom-in و بیرون آمدن از zoom یا zoom-out را handle کند و زمانی که کاربر بروی عکس دوبار کلیک کرد عکس zoom-out شود
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 | 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 خود شده کد زیر را قرار دهید.
1 2 3 4 5 6 7 8 | <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"/> |
حالا نحوه استفاده از آن به شکل زیر می شود وارد اکتیویتی خود شده و کد زیر را قرار دهید.
1 2 3 | 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) زوم کرد؟
آره واقعا سوال من هم هست لطفا جواب بدید