How to Implement Zoom Effect for Image View in Android

Android ImageView Zoom-in and Zoom-Out

Make two java classes

Zoom class

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.drawable.Drawable;
import android.view.KeyEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageButton;

public class Zoom extends View {

private Drawable image;
ImageButton img,img1;
private int zoomControler=20;

public Zoom(Context context){
super(context);

image=context.getResources().getDrawable(R.drawable.j);
//image=context.getResources().getDrawable(R.drawable.icon);

setFocusable(true);
}

@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);

//here u can control the width and height of the images........ this line is very important
image.setBounds((getWidth()/2)-zoomControler, (getHeight()/2)-zoomControler, (getWidth()/2)+zoomControler, (getHeight()/2)+zoomControler);
image.draw(canvas);
}

@Override
public boolean onKeyDown(int keyCode, KeyEvent event) {

if(keyCode==KeyEvent.KEYCODE_DPAD_UP){
// zoom in
zoomControler+=10;
}
if(keyCode==KeyEvent.KEYCODE_DPAD_DOWN){
// zoom out
zoomControler-=10;
}
if(zoomControler<10){
zoomControler=10;
}

invalidate();
return true;
}
}

make second class

import android.app.Activity;
import android.os.Bundle;

public class Zoomexample extends Activity {
/** Called when the activity is first created. */

@Override
public void onCreate(Bundle icicle) {
super.onCreate(icicle);
setContentView(new Zoom(this));
}
}

ImageView zooming in android through code

Below are the options available for implementing zoom in-out effect in android Imageview.

  1. How to implement zoom effect for image view in android?
  2. Android imageView Zoom-in and Zoom-Out
  3. https://github.com/chrisbanes/PhotoView

How to implement zoom effect for image view in android?

Lazy man can use this lib, Just import inside your project and

ImageView mImageView;
PhotoViewAttacher mAttacher;

@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);

// Any implementation of ImageView can be used!
mImageView = (ImageView) findViewById(R.id.iv_photo);

// Set the Drawable displayed
Drawable bitmap = getResources().getDrawable(R.drawable.wallpaper);
mImageView.setImageDrawable(bitmap);

// Attach a PhotoViewAttacher, which takes care of all of the zooming functionality.
mAttacher = new PhotoViewAttacher(mImageView);
}

// If you later call mImageView.setImageDrawable/setImageBitmap/setImageResource/etc then you just need to call
mAttacher.update();

Android ImageView Zooming Effect

After quite a few days of trying to solve this particular issue, I, thanks to those answers above and other sources, was able to write full working code.

To save time for all of you guys here it is. Copy-paste and edit it a bit to fit your goals.

First of all you need to edit your main activity - we're going to use custom ImageView

 <your.package.name.ZoomView
android:id="@+id/imageView1"
android:layout_width="wrap_content"
android:layout_height="wrap_content"/>

Then we'll edit MainActivity.java. Use ZoomView just like ImageView

ImageView takenPhoto;
takenPhoto = (ZoomView) findViewById(R.id.imageView1);

After, create ZoomView class and paste this:

public class ZoomView extends ImageView {

PointF zoomPos;
boolean zooming;
Matrix matrix;
BitmapShader mShader;
Paint mPaint;

public ZoomView(Context context) {
super(context);
}

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

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

@Override
public boolean onTouchEvent(@NonNull MotionEvent event) {
zoomPos = new PointF();
zoomPos.x = event.getX();
zoomPos.y = event.getY();

matrix = new Matrix();
mShader = new BitmapShader(MainActivity.mutableBitmap, TileMode.CLAMP, TileMode.CLAMP);
mPaint = new Paint();
mPaint.setShader(mShader);

int action = event.getAction();

switch (action) {
case MotionEvent.ACTION_DOWN:
case MotionEvent.ACTION_MOVE:
zooming = true;
this.invalidate();
break;
case MotionEvent.ACTION_UP:
zooming = false;
this.invalidate();
break;
case MotionEvent.ACTION_CANCEL:
zooming = false;
this.invalidate();
break;

default:
break;
}
return true;
}

@Override
protected void onDraw(@NonNull Canvas canvas) {
super.onDraw(canvas);
if (zooming) {
matrix.reset();
matrix.postScale(2f, 2f, zoomPos.x, zoomPos.y);
mPaint.getShader().setLocalMatrix(matrix);
canvas.drawCircle(zoomPos.x, zoomPos.y, 100, mPaint);
}
}
}

Now you should have working magnifying effect.

Adding azoom effect to an ImageView like gallery images

You can create your own custom ImageView. I found this useful.

/**
* Copyright 2012-2013 Jeremie Martinez (jeremiemartinez@gmail.com)
* <p>
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
* <p>
* http://www.apache.org/licenses/LICENSE-2.0
* <p>
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*/

import android.content.Context;
import android.graphics.Matrix;
import android.graphics.PointF;
import android.support.v7.widget.AppCompatImageView;
import android.util.AttributeSet;
import android.view.GestureDetector;
import android.view.MotionEvent;
import android.view.ScaleGestureDetector;

/**
* @author jmartinez
*
* Simple Android ImageView that enables dragging and zooming.
*
*/
public class ZoomableImageView extends AppCompatImageView {

private float maxScale = 3f;
private float minScale = 1f;

private enum State {
INIT, DRAG, ZOOM
}

private State state;

private Matrix matrix;
private float[] finalTransformation = new float[9];
private PointF last = new PointF();
private float currentScale = 1f;

private int viewWidth;
private int viewHeight;
private float afterScaleDrawableWidth;
private float afterScaleDrawableHeight;

private ScaleGestureDetector scaleDetector;

private GestureDetector doubleTapDetecture;

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

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

public ZoomableImageView(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
setUp(context);
}

@Override
protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
super.onMeasure(widthMeasureSpec, heightMeasureSpec);
viewWidth = MeasureSpec.getSize(widthMeasureSpec);
viewHeight = MeasureSpec.getSize(heightMeasureSpec);

// Set up drawable at first load
if (hasDrawable()) {
resetImage();
}
}

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

PointF current = new PointF(event.getX(), event.getY());

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
last.set(current);
state = State.DRAG;
break;

case MotionEvent.ACTION_MOVE:
if (state == State.DRAG) {
drag(current);
last.set(current);
}
break;

case MotionEvent.ACTION_UP:
state = State.INIT;
break;

case MotionEvent.ACTION_POINTER_UP:
state = State.INIT;
break;
}

setImageMatrix(matrix);
invalidate();
return true;
}

/**
* Set up the class. Method called by constructors.
*
* @param context
*/
private void setUp(Context context) {
super.setClickable(false);
matrix = new Matrix();
state = State.INIT;
scaleDetector = new ScaleGestureDetector(context, new ScaleListener());
doubleTapDetecture = new GestureDetector(context, new GestureListener());
setScaleType(ScaleType.MATRIX);
}

private void resetImage() {

// Scale Image
float scale = getScaleForDrawable();
matrix.setScale(scale, scale);

// Center Image
float marginY = ((float) viewHeight - (scale * getDrawable().getIntrinsicHeight())) / 2;
float marginX = ((float) viewWidth - (scale * getDrawable().getIntrinsicWidth())) / 2;
matrix.postTranslate(marginX, marginY);

afterScaleDrawableWidth = (float) viewWidth - 2 * marginX;
afterScaleDrawableHeight = (float) viewHeight - 2 * marginY;

setImageMatrix(matrix);
}

/**
* Getter and setter for max/min scale. Default are min=1 and max=3
*/

public float getMaxScale() {
return maxScale;
}

public void setMaxScale(float maxScale) {
this.maxScale = maxScale;
}

public float getMinScale() {
return minScale;
}

public void setMinScale(float minScale) {
this.minScale = minScale;
}

/**
* Drag method
*
* @param current
* Current point to drag to.
*/
private void drag(PointF current) {
float deltaX = getMoveDraggingDelta(current.x - last.x, viewWidth, afterScaleDrawableWidth * currentScale);
float deltaY = getMoveDraggingDelta(current.y - last.y, viewHeight, afterScaleDrawableHeight * currentScale);
matrix.postTranslate(deltaX, deltaY);
limitDrag();
}

/**
* Scale method for zooming
*
* @param focusX
* X of center of scale
* @param focusY
* Y of center of scale
* @param scaleFactor
* scale factor to zoom in/out
*/
private void scale(float focusX, float focusY, float scaleFactor) {
float lastScale = currentScale;
float newScale = lastScale * scaleFactor;

// Calculate next scale with resetting to max or min if required
if (newScale > maxScale) {
currentScale = maxScale;
scaleFactor = maxScale / lastScale;
} else if (newScale < minScale) {
currentScale = minScale;
scaleFactor = minScale / lastScale;
} else {
currentScale = newScale;
}

// Do scale
if (requireCentering()) {
matrix.postScale(scaleFactor, scaleFactor, (float) viewWidth / 2, (float) viewHeight / 2);
} else
matrix.postScale(scaleFactor, scaleFactor, focusX, focusY);

limitDrag();
}

/**
* This method permits to keep drag and zoom inside the drawable. It makes sure the drag is staying in bound.
*/
private void limitDrag() {
matrix.getValues(finalTransformation);
float finalXTransformation = finalTransformation[Matrix.MTRANS_X];
float finalYTransformation = finalTransformation[Matrix.MTRANS_Y];

float deltaX = getScaleDraggingDelta(finalXTransformation, viewWidth, afterScaleDrawableWidth * currentScale);
float deltaY = getScaleDraggingDelta(finalYTransformation, viewHeight, afterScaleDrawableHeight * currentScale);

matrix.postTranslate(deltaX, deltaY);
}

private float getScaleDraggingDelta(float delta, float viewSize, float contentSize) {
float minTrans = 0;
float maxTrans = 0;

if (contentSize <= viewSize) {
maxTrans = viewSize - contentSize;
} else {
minTrans = viewSize - contentSize;
}

if (delta < minTrans)
return minTrans - delta;
else if (delta > maxTrans)
return maxTrans - delta;
else
return 0;
}

// Check if dragging is still possible if so return delta otherwise return 0 (do nothing)
private float getMoveDraggingDelta(float delta, float viewSize, float contentSize) {
if (contentSize <= viewSize) {
return 0;
}
return delta;
}

private float getScaleForDrawable() {
float scaleX = (float) viewWidth / (float) getDrawable().getIntrinsicWidth();
float scaleY = (float) viewHeight / (float) getDrawable().getIntrinsicHeight();
return Math.min(scaleX, scaleY);
}

private boolean hasDrawable() {
return getDrawable() != null && getDrawable().getIntrinsicWidth() != 0 && getDrawable().getIntrinsicHeight() != 0;
}

private boolean requireCentering() {
return afterScaleDrawableWidth * currentScale <= (float) viewWidth || afterScaleDrawableHeight * currentScale <= (float) viewHeight;
}

private boolean isZoom() {
return currentScale != 1f;
}

/**
* Listener for detecting scale.
*
* @author jmartinez
*/
private class ScaleListener extends ScaleGestureDetector.SimpleOnScaleGestureListener {
@Override
public boolean onScaleBegin(ScaleGestureDetector detector) {
state = State.ZOOM;
return true;
}

@Override
public boolean onScale(ScaleGestureDetector detector) {
scale(detector.getFocusX(), detector.getFocusY(), detector.getScaleFactor());
return true;
}
}

/**
* Listener for double tap detection
*
* @author jmartinez
*/
private class GestureListener extends GestureDetector.SimpleOnGestureListener {

@Override
public boolean onDoubleTap(MotionEvent e) {
if (isZoom()) {
resetImage();
currentScale = 1f;
state = State.INIT;

} else {
scale(e.getX(), e.getY(), maxScale);
}
return true;
}

}

}

Then instead of ImageView you can use ...yourpackage.ZoomableImageView

Zoom An Image ( Android Studio )

You can use this library. This is the perfect library according to your requirement. You can also apply zoom in/out for video.

https://github.com/natario1/ZoomLayout



Related Topics



Leave a reply



Submit